From fc45d42d01fba4f858012740e6a8a43ce5ecad9b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 3 Jan 2007 10:12:55 -0800 Subject: [PATCH 01/37] Add 'Time' as a parameter type that can accept various formats for time (strings, datetime objects, etc.) Advance system time to 1/1/2009 Clean up time management code a little bit --HG-- extra : convert_revision : 28ebecc7ea6b12f4345c77a9a6b4bdf2e752c4f8 --- src/dev/alpha/tsunami_io.cc | 11 ++----- src/dev/alpha/tsunami_io.hh | 5 +-- src/python/m5/objects/Tsunami.py | 4 +-- src/python/m5/params.py | 52 +++++++++++++++++++++++++++++++- 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc index 8430856ef..38986b77e 100644 --- a/src/dev/alpha/tsunami_io.cc +++ b/src/dev/alpha/tsunami_io.cc @@ -57,17 +57,13 @@ using namespace std; //Should this be AlphaISA? using namespace TheISA; -TsunamiIO::RTC::RTC(const string &name, Tsunami* t, Tick i) - : _name(name), event(t, i), addr(0) +TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, time_t t, Tick i) + : _name(n), event(tsunami, i), addr(0) { memset(clock_data, 0, sizeof(clock_data)); stat_regA = RTCA_32768HZ | RTCA_1024HZ; stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR; -} -void -TsunamiIO::RTC::set_time(time_t t) -{ struct tm tm; gmtime_r(&t, &tm); @@ -428,7 +424,7 @@ TsunamiIO::PITimer::Counter::CounterEvent::description() TsunamiIO::TsunamiIO(Params *p) : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), - rtc(p->name + ".rtc", p->tsunami, p->frequency) + rtc(p->name + ".rtc", p->tsunami, p->init_time, p->frequency) { pioSize = 0x100; @@ -436,7 +432,6 @@ TsunamiIO::TsunamiIO(Params *p) tsunami->io = this; timerData = 0; - rtc.set_time(p->init_time == 0 ? time(NULL) : p->init_time); picr = 0; picInterrupting = false; } diff --git a/src/dev/alpha/tsunami_io.hh b/src/dev/alpha/tsunami_io.hh index 54acefc25..b0c368eb8 100644 --- a/src/dev/alpha/tsunami_io.hh +++ b/src/dev/alpha/tsunami_io.hh @@ -110,10 +110,7 @@ class TsunamiIO : public BasicPioDevice uint8_t stat_regB; public: - RTC(const std::string &name, Tsunami* t, Tick i); - - /** Set the initial RTC time/date */ - void set_time(time_t t); + RTC(const std::string &name, Tsunami* tsunami, time_t t, Tick i); /** RTC address port: write address of RTC RAM data to access */ void writeAddr(const uint8_t data); diff --git a/src/python/m5/objects/Tsunami.py b/src/python/m5/objects/Tsunami.py index ac9020b47..18a776a7f 100644 --- a/src/python/m5/objects/Tsunami.py +++ b/src/python/m5/objects/Tsunami.py @@ -13,8 +13,8 @@ class TsunamiCChip(BasicPioDevice): class TsunamiIO(BasicPioDevice): type = 'TsunamiIO' - time = Param.UInt64(1136073600, - "System time to use (0 for actual time, default is 1/1/06)") + time = Param.Time('01/01/2009', + "System time to use ('Now' for actual time)") tsunami = Param.Tsunami(Parent.any, "Tsunami") frequency = Param.Frequency('1024Hz', "frequency of interrupts") diff --git a/src/python/m5/params.py b/src/python/m5/params.py index d83d5f73f..d570804d8 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -44,7 +44,12 @@ # ##################################################################### -import sys, inspect, copy +import copy +import datetime +import inspect +import sys +import time + import convert from util import * @@ -513,6 +518,50 @@ class EthernetAddr(ParamValue): else: return self.value +def parse_time(value): + strings = [ "%a %b %d %H:%M:%S %Z %Y", + "%a %b %d %H:%M:%S %Z %Y", + "%Y/%m/%d %H:%M:%S", + "%Y/%m/%d %H:%M", + "%Y/%m/%d", + "%m/%d/%Y %H:%M:%S", + "%m/%d/%Y %H:%M", + "%m/%d/%Y", + "%m/%d/%y %H:%M:%S", + "%m/%d/%y %H:%M", + "%m/%d/%y"] + + for string in strings: + try: + return time.strptime(value, string) + except ValueError: + pass + + raise ValueError, "Could not parse '%s' as a time" % value + +class Time(ParamValue): + cxx_type = 'time_t' + def __init__(self, value): + if isinstance(value, time.struct_time): + self.value = time.mktime(value) + elif isinstance(value, int): + self.value = value + elif isinstance(value, str): + if value in ('Now', 'Today'): + self.value = time.time() + else: + self.value = time.mktime(parse_time(value)) + elif isinstance(value, (datetime.datetime, datetime.date)): + self.value = time.mktime(value.timetuple()) + else: + raise ValueError, "Could not parse '%s' as a time" % value + + def __str__(self): + return str(int(self.value)) + + def ini_str(self): + return str(int(self.value)) + # Enumerated types are a little more complex. The user specifies the # type as Enum(foo) where foo is either a list or dictionary of # alternatives (typically strings, but not necessarily so). (In the @@ -973,6 +1022,7 @@ __all__ = ['Param', 'VectorParam', 'NetworkBandwidth', 'MemoryBandwidth', 'Range', 'AddrRange', 'TickRange', 'MaxAddr', 'MaxTick', 'AllMemory', + 'Time', 'NextEthernetAddr', 'NULL', 'Port', 'VectorPort'] From e9a395c2ce35bb0b46389ea3d73655e0bc824944 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 3 Jan 2007 10:13:45 -0800 Subject: [PATCH 02/37] Formatting --HG-- extra : convert_revision : bf1eae73995f772a4343c8ebcb254818eeb5d949 --- src/cpu/cpuevent.hh | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/cpu/cpuevent.hh b/src/cpu/cpuevent.hh index 3339f8252..c973621c0 100644 --- a/src/cpu/cpuevent.hh +++ b/src/cpu/cpuevent.hh @@ -36,12 +36,14 @@ class ThreadContext; -/** This class creates a global list of events that need a pointer to a - * thread context. When a switchover takes place the events can be migrated - * to the new thread context, otherwise you could have a wake timer interrupt - * go off on a switched out cpu or other unfortunate events. This object MUST be - * dynamically allocated to avoid it being deleted after a cpu switch happens. - * */ +/** + * This class creates a global list of events that need a pointer to a + * thread context. When a switchover takes place the events can be + * migrated to the new thread context, otherwise you could have a wake + * timer interrupt go off on a switched out cpu or other unfortunate + * events. This object MUST be dynamically allocated to avoid it being + * deleted after a cpu switch happens. + */ class CpuEvent : public Event { protected: @@ -78,8 +80,8 @@ class CpuEventWrapper : public CpuEvent T *object; public: - CpuEventWrapper(T *obj, ThreadContext *_tc, EventQueue *q = &mainEventQueue, - Priority p = Default_Pri) + CpuEventWrapper(T *obj, ThreadContext *_tc, + EventQueue *q = &mainEventQueue, Priority p = Default_Pri) : CpuEvent(q, _tc, p), object(obj) { } void process() { (object->*F)(tc); } From e6b4fed75d8b1044835bfbef77934b9a47bb2680 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 3 Jan 2007 10:16:22 -0800 Subject: [PATCH 03/37] set __name__ in the root m5 script to __m5_main__ so we can tell if the script is run from m5 as the m5 script --HG-- extra : convert_revision : 06f646cbb8c82444ef345115aa49324a4d3a2c9f --- src/python/m5/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 114c668a6..5df6d03cf 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -304,7 +304,8 @@ def main(): sys.argv = arguments sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path - scope = { '__file__' : sys.argv[0] } + scope = { '__file__' : sys.argv[0], + '__name__' : '__m5_main__' } # we want readline if we're doing anything interactive if options.interactive or options.pdb: From b46aa884354451fdf642ea836e3442d4179e73fb Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 4 Jan 2007 20:22:45 -0500 Subject: [PATCH 04/37] Fix stick compare to work correctly and set checkInterrupts to true at the appropriate time turn warnings into dprintfs src/arch/sparc/miscregfile.cc: turn dprintfn into dprintfs --HG-- extra : convert_revision : cd313e9037c8f040d837de4c7ddbcf98534e60ad --- src/arch/sparc/miscregfile.cc | 6 +++--- src/arch/sparc/ua2005.cc | 35 +++++++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 53559c072..68c6fa84a 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -321,9 +321,9 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) // I'm not sure why legion ignores the lowest two bits, but we'll go // with it // change from curCycle() to instCount() until we're done with legion - DPRINTFN("Instruction Count when TICK read: %#X stick=%#X\n", + DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n", tc->getCpuPtr()->instCount(), stick); - return mbits(tc->getCpuPtr()->instCount() + (int32_t)stick,62,2) | + return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) | mbits(tick,63,63); case MISCREG_FPRS: warn("FPRS register read and FPU stuff not really implemented\n"); @@ -615,7 +615,7 @@ void MiscRegFile::setRegWithEffect(int miscReg, // use stick for offset and tick for holding intrrupt bit stick = mbits(val,62,0) - tc->getCpuPtr()->instCount(); tick = mbits(val,63,63); - DPRINTFN("Writing TICK=%#X\n", val); + DPRINTF(Timer, "Writing TICK=%#X\n", val); break; case MISCREG_FPRS: //Configure the fpu based on the fprs diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 0db5f6acc..66d699fce 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -64,19 +64,20 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, time = (tick_cmpr & mask(63)) - (tick & mask(63)); if (!(tick_cmpr & ~mask(63)) && time > 0) tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); - warn ("writing to TICK compare register %#X\n", val); + panic("writing to TICK compare register %#X\n", val); break; case MISCREG_STICK_CMPR: if (sTickCompare == NULL) sTickCompare = new STickCompareEvent(this, tc); setReg(miscReg, val); - if ((stick_cmpr & mask(63)) && sTickCompare->scheduled()) + if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) sTickCompare->deschedule(); - time = (stick_cmpr & mask(63)) - (stick & mask(63)); + time = ((int64_t)(stick_cmpr & mask(63)) + (int64_t)stick) - + tc->getCpuPtr()->instCount(); if (!(stick_cmpr & ~mask(63)) && time > 0) - sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); - warn ("writing to sTICK compare register value %#X\n", val); + sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); + DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); break; case MISCREG_PSTATE: @@ -116,11 +117,12 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, if (hSTickCompare == NULL) hSTickCompare = new HSTickCompareEvent(this, tc); setReg(miscReg, val); - if ((hstick_cmpr & mask(63)) && hSTickCompare->scheduled()) + if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) hSTickCompare->deschedule(); - time = (hstick_cmpr & mask(63)) - (stick & mask(63)); + time = ((int64_t)(hstick_cmpr & mask(63)) + (int64_t)stick) - + tc->getCpuPtr()->instCount(); if (!(hstick_cmpr & ~mask(63)) && time > 0) - hSTickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); + hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); warn ("writing to hsTICK compare register value %#X\n", val); break; @@ -191,12 +193,25 @@ MiscRegFile::processTickCompare(ThreadContext *tc) void MiscRegFile::processSTickCompare(ThreadContext *tc) { - panic("tick compare not implemented\n"); + // since our microcode instructions take two cycles we need to check if + // we're actually at the correct cycle or we need to wait a little while + // more + int ticks; + ticks = (stick_cmpr & mask(63)) - tc->getCpuPtr()->instCount(); + assert(ticks >= 0 && "stick compare missed interrupt cycle"); + + if (ticks == 0) { + DPRINTF(Timer, "STick compare cycle reached at %#x\n", + (stick_cmpr & mask(63))); + tc->getCpuPtr()->checkInterrupts = true; + + } else + sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); } void MiscRegFile::processHSTickCompare(ThreadContext *tc) { - panic("tick compare not implemented\n"); + panic("hstick compare not implemented\n"); } From 4a8078192d77f60580a79762156124e6331ea310 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 5 Jan 2007 15:04:17 -0500 Subject: [PATCH 05/37] set the softint appropriately on an timer compare interrupt there is no interrupt_level_0 interrupt, so start the list at 0x40 so the adding is done correctly src/arch/sparc/faults.cc: there is no interrupt_level_0 interrupt, so start the list at 0x40 so the adding is done correctly src/arch/sparc/faults.hh: correct protection defines src/arch/sparc/ua2005.cc: set the softint appropriately on an timer compare interrupt --HG-- extra : convert_revision : f41c10ec78db973b3f856c70b58a17f83b60bbe2 --- src/arch/sparc/faults.cc | 2 +- src/arch/sparc/faults.hh | 6 +++--- src/arch/sparc/ua2005.cc | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 64cfc832a..af80238df 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -197,7 +197,7 @@ template<> SparcFaultBase::FaultVals template<> SparcFaultBase::FaultVals SparcFault::vals = - {"interrupt_level_n", 0x041, 0, {P, P, SH}}; + {"interrupt_level_n", 0x040, 0, {P, P, SH}}; template<> SparcFaultBase::FaultVals SparcFault::vals = diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index e632502aa..6b3820ddd 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -29,8 +29,8 @@ * Kevin Lim */ -#ifndef __ALPHA_FAULTS_HH__ -#define __ALPHA_FAULTS_HH__ +#ifndef __SPARC_FAULTS_HH__ +#define __SPARC_FAULTS_HH__ #include "sim/faults.hh" @@ -280,4 +280,4 @@ static inline Fault genAlignmentFault() } // SparcISA namespace -#endif // __FAULTS_HH__ +#endif // __SPARC_FAULTS_HH__ diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 66d699fce..c7d2ffce5 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -73,7 +73,7 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, setReg(miscReg, val); if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) sTickCompare->deschedule(); - time = ((int64_t)(stick_cmpr & mask(63)) + (int64_t)stick) - + time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - tc->getCpuPtr()->instCount(); if (!(stick_cmpr & ~mask(63)) && time > 0) sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); @@ -197,14 +197,15 @@ MiscRegFile::processSTickCompare(ThreadContext *tc) // we're actually at the correct cycle or we need to wait a little while // more int ticks; - ticks = (stick_cmpr & mask(63)) - tc->getCpuPtr()->instCount(); + ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - + tc->getCpuPtr()->instCount(); assert(ticks >= 0 && "stick compare missed interrupt cycle"); if (ticks == 0) { DPRINTF(Timer, "STick compare cycle reached at %#x\n", (stick_cmpr & mask(63))); tc->getCpuPtr()->checkInterrupts = true; - + softint |= ULL(1) << 16; } else sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); } From 2f4239a68539916a3822fa76346f9487c39304f3 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 8 Jan 2007 17:09:48 -0500 Subject: [PATCH 06/37] fix softint and partially implement hstick interrupts need to figure out how to do the acutal interrupting still src/arch/sparc/miscregfile.cc: fix softint and fprs in miscregfile --HG-- extra : convert_revision : cf98bd9c172e20f328f18e07dd05f63f37f14c87 --- src/arch/sparc/miscregfile.cc | 10 ++++++++-- src/arch/sparc/ua2005.cc | 24 +++++++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 68c6fa84a..c58a1fd09 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -327,7 +327,11 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) mbits(tick,63,63); case MISCREG_FPRS: warn("FPRS register read and FPU stuff not really implemented\n"); - return fprs; + // in legion if fp is enabled du and dl are set + if (fprs & 0x4) + return 0x7; + else + return 0; case MISCREG_PCR: case MISCREG_PIC: panic("Performance Instrumentation not impl\n"); @@ -399,7 +403,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) gsr = val; break; case MISCREG_SOFTINT: - softint |= val; + softint = val; break; case MISCREG_TICK_CMPR: tick_cmpr = val; @@ -637,6 +641,8 @@ void MiscRegFile::setRegWithEffect(int miscReg, break; case MISCREG_PIL: case MISCREG_SOFTINT: + case MISCREG_SOFTINT_SET: + case MISCREG_SOFTINT_CLR: case MISCREG_TICK_CMPR: case MISCREG_STICK_CMPR: case MISCREG_HINTP: diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index c7d2ffce5..1f7f65045 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -51,9 +51,9 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, break; case MISCREG_SOFTINT_CLR: - return setRegWithEffect(miscReg, ~val & softint, tc); + return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); case MISCREG_SOFTINT_SET: - return setRegWithEffect(miscReg, val | softint, tc); + return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); case MISCREG_TICK_CMPR: if (tickCompare == NULL) @@ -119,11 +119,11 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, setReg(miscReg, val); if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) hSTickCompare->deschedule(); - time = ((int64_t)(hstick_cmpr & mask(63)) + (int64_t)stick) - + time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - tc->getCpuPtr()->instCount(); if (!(hstick_cmpr & ~mask(63)) && time > 0) hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); - warn ("writing to hsTICK compare register value %#X\n", val); + DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); break; case MISCREG_HPSTATE: @@ -213,6 +213,20 @@ MiscRegFile::processSTickCompare(ThreadContext *tc) void MiscRegFile::processHSTickCompare(ThreadContext *tc) { - panic("hstick compare not implemented\n"); + // since our microcode instructions take two cycles we need to check if + // we're actually at the correct cycle or we need to wait a little while + // more + int ticks; + ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - + tc->getCpuPtr()->instCount(); + assert(ticks >= 0 && "hstick compare missed interrupt cycle"); + + if (ticks == 0) { + DPRINTF(Timer, "HSTick compare cycle reached at %#x\n", + (stick_cmpr & mask(63))); + tc->getCpuPtr()->checkInterrupts = true; + // Need to do something to cause interrupt to happen here !!! @todo + } else + sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); } From a8b2d66661e4be7cf5d5856f75f3f0e7849c5a9f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 8 Jan 2007 17:11:10 -0500 Subject: [PATCH 07/37] change when legion-lock causes the simulation to die. It now happens after two consuctive differences since we compare stuff at slightly different times interrupts are seen the cycle before they happen in m5 so the pc gets changed early. --HG-- extra : convert_revision : f237363eababb2aad67e5b41670cf40be048a042 --- src/cpu/exetrace.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 352a11958..6e0bf6d33 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -609,7 +609,8 @@ Trace::InstRecord::dump(ostream &outs) diffcount++; if (diffcount > 2) fatal("Differences found between Legion and M5\n"); - } + } else + diffcount = 0; compared = true; shared_data->flags = OWN_LEGION; From b45219e7ae747619571dbb7245dd3409b96c473f Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 8 Jan 2007 18:07:17 -0500 Subject: [PATCH 08/37] some formatting changes, and update how I do bitfields for HPSTATE and PSTATE to avoid name confusion. src/arch/sparc/faults.cc: 1) s/Resumeable/Resumable/gc 2) s/if(/if (/gc 3) keep variables lowercase 4) change the way fields are accessed - instead of hard coding bitvectors, use masks (like HPSTATE::hpriv). src/arch/sparc/faults.hh: s/Resumeable/Resumable/ src/arch/sparc/isa_traits.hh: This is unused and unnecessary. src/arch/sparc/miscregfile.hh: add bitfield masks for some important ASRs (HPSTATE, PSTATE). --HG-- extra : convert_revision : f0ffaf48de298758685266dfb90f43aff42e0a2c --- src/arch/sparc/faults.cc | 40 +++++++++++++++++------------------ src/arch/sparc/faults.hh | 2 +- src/arch/sparc/isa_traits.hh | 9 -------- src/arch/sparc/miscregfile.hh | 30 ++++++++++++++------------ 4 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index af80238df..a74eebafa 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -240,7 +240,7 @@ template<> SparcFaultBase::FaultVals {"dev_mondo", 0x07D, 1611, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = + SparcFault::vals = {"resume_error", 0x07E, 3330, {P, P, SH}}; template<> SparcFaultBase::FaultVals @@ -436,7 +436,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) tc->setMiscReg(MISCREG_TT, tt); //Update the global register level - if(!gotoHpriv) + if (!gotoHpriv) tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxPGL)); else tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxGL)); @@ -448,7 +448,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) PSTATE |= (1 << 4); //PSTATE.am = 0 PSTATE &= ~(1 << 3); - if(!gotoHpriv) + if (!gotoHpriv) { //PSTATE.priv = 1 PSTATE |= (1 << 2); @@ -471,7 +471,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) //XXX Where exactly is this field? tc->setMiscReg(MISCREG_PSTATE, PSTATE); - if(gotoHpriv) + if (gotoHpriv) { //HPSTATE.red = 0 HPSTATE &= ~(1 << 5); @@ -484,16 +484,16 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) } bool changedCWP = true; - if(tt == 0x24) + if (tt == 0x24) CWP++; - else if(0x80 <= tt && tt <= 0xbf) + else if (0x80 <= tt && tt <= 0xbf) CWP += (CANSAVE + 2); - else if(0xc0 <= tt && tt <= 0xff) + else if (0xc0 <= tt && tt <= 0xff) CWP--; else changedCWP = false; - if(changedCWP) + if (changedCWP) { CWP = (CWP + NWindows) % NWindows; tc->setMiscRegWithEffect(MISCREG_CWP, CWP); @@ -534,45 +534,45 @@ void SparcFaultBase::invoke(ThreadContext * tc) //We can refer to this to see what the trap level -was-, but something //in the middle could change it in the regfile out from under us. - MiscReg TL = tc->readMiscReg(MISCREG_TL); - MiscReg TT = tc->readMiscReg(MISCREG_TT); - MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); - MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + MiscReg tl = tc->readMiscReg(MISCREG_TL); + MiscReg tt = tc->readMiscReg(MISCREG_TT); + MiscReg pstate = tc->readMiscReg(MISCREG_PSTATE); + MiscReg hpstate = tc->readMiscReg(MISCREG_HPSTATE); Addr PC, NPC; PrivilegeLevel current; - if(HPSTATE & (1 << 2)) + if (hpstate & HPSTATE::hpriv) current = Hyperprivileged; - else if(PSTATE & (1 << 2)) + else if (pstate & PSTATE::priv) current = Privileged; else current = User; PrivilegeLevel level = getNextLevel(current); - if(HPSTATE & (1 << 5) || TL == MaxTL - 1) { + if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) { getREDVector(5, PC, NPC); - doREDFault(tc, TT); + doREDFault(tc, tt); //This changes the hpstate and pstate, so we need to make sure we //save the old version on the trap stack in doREDFault. enterREDState(tc); - } else if(TL == MaxTL) { + } else if (tl == MaxTL) { panic("Should go to error state here.. crap\n"); //Do error_state somehow? //Probably inject a WDR fault using the interrupt mechanism. //What should the PC and NPC be set to? - } else if(TL > MaxPTL && level == Privileged) { + } else if (tl > MaxPTL && level == Privileged) { //guest_watchdog fault doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, 2); - } else if(level == Hyperprivileged || + } else if (level == Hyperprivileged || level == Privileged && trapType() >= 384) { doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, trapType()); } else { doNormalFault(tc, trapType(), false); - getPrivVector(tc, PC, NPC, trapType(), TL+1); + getPrivVector(tc, PC, NPC, trapType(), tl+1); } tc->setPC(PC); diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 6b3820ddd..3c0d9674f 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -210,7 +210,7 @@ class CpuMondo : public SparcFault {}; class DevMondo : public SparcFault {}; -class ResumeableError : public SparcFault {}; +class ResumableError : public SparcFault {}; class SpillNNormal : public EnumeratedFault { diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 3f0b9cad5..8aa8ea7f3 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -96,15 +96,6 @@ namespace SparcISA StaticInstPtr decodeInst(ExtMachInst); #if FULL_SYSTEM - ////////// Interrupt Stuff /////////// - enum InterruptLevels - { - INTLEVEL_MIN = 1, - INTLEVEL_MAX = 15, - - NumInterruptLevels = INTLEVEL_MAX - INTLEVEL_MIN - }; - // I don't know what it's for, so I don't // know what SPARC's value should be // For loading... XXX This maybe could be USegEnd?? --ali diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index c879fd357..8a2e8e810 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -142,24 +142,26 @@ namespace SparcISA MISCREG_NUMMISCREGS }; - enum HPStateFields { - id = 0x800, // this impl. dependent (id) field must always be '1' for T1000 - ibe = 0x400, - red = 0x20, - hpriv = 0x4, - tlz = 0x1 + struct HPSTATE { + const static uint64_t id = 0x800; // this impl. dependent (id) field m + const static uint64_t ibe = 0x400; + const static uint64_t red = 0x20; + const static uint64_t hpriv = 0x4; + const static uint64_t tlz = 0x1; }; - enum PStateFields { - cle = 0x200, - tle = 0x100, - mm = 0xC0, - pef = 0x10, - am = 0x8, - priv = 0x4, - ie = 0x2 + + struct PSTATE { + const static int cle = 0x200; + const static int tle = 0x100; + const static int mm = 0xC0; + const static int pef = 0x10; + const static int am = 0x8; + const static int priv = 0x4; + const static int ie = 0x2; }; + const int NumMiscArchRegs = MISCREG_NUMMISCREGS; const int NumMiscRegs = MISCREG_NUMMISCREGS; From 032ea9b2db870ad9b2a039f8c4020e38f5dd7f62 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 8 Jan 2007 18:18:28 -0500 Subject: [PATCH 09/37] the way i understand it, interrupts in m5 is a little bloated. the usage of CPU->checkInterrupts bool is inconsistent, and i think should eventually be phased out. For now, I've just assumed that CPU->checkInterrupts() is the way to fast path a CPU if you have no interrupts by having a simple bitfield in each ISA to determine whether interrupts are pending. getInterrupts has been mostly filled in. src/arch/sparc/interrupts.hh: fill in how we do interrupts on sparc a little bit. 1) create a bitfield for interrupts, and check that in checkInterrupts() to fast path CPU. 2) fill in getInterrupts() a little bit. also, update the bitfield access to be HPSTATE::hpriv, etc. src/arch/sparc/ua2005.cc: 1) update formatting 2) change the way interrupts are done to use the new way to tickle the CPU. src/cpu/base.cc: src/cpu/base.hh: overload the post_interrupt function for SPARC interrupts - which are only denoted by a single int value. --HG-- extra : convert_revision : 9074a003eff37a40dcce78f56d20f6cbcc453eb5 --- src/arch/sparc/interrupts.hh | 125 +++++++++++++++++++++-- src/arch/sparc/ua2005.cc | 188 ++++++++++++++++++----------------- src/cpu/base.cc | 6 ++ src/cpu/base.hh | 1 + 4 files changed, 219 insertions(+), 101 deletions(-) diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 452164e46..76bd4c6e2 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -34,19 +34,45 @@ #include "arch/sparc/faults.hh" #include "cpu/thread_context.hh" - namespace SparcISA { + +enum interrupts_t { + trap_level_zero, + hstick_match, + interrupt_vector, + cpu_mondo, + dev_mondo, + resumable_error, + soft_interrupt, + num_interrupt_types +}; + class Interrupts { - protected: + private: + + bool interrupts[num_interrupt_types]; + int numPosted; public: Interrupts() { - + for (int i = 0; i < num_interrupt_types; ++i) { + interrupts[i] = false; + } + numPosted = 0; } + + void post(int int_type) + { + if (int_type < 0 || int_type >= num_interrupt_types) + panic("posting unknown interrupt!\n"); + interrupts[int_type] = true; + ++numPosted; + } + void post(int int_num, int index) { @@ -64,9 +90,7 @@ namespace SparcISA bool check_interrupts(ThreadContext * tc) const { - // so far only handle softint interrupts - int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); - if (int_level) + if (numPosted) return true; else return false; @@ -74,14 +98,99 @@ namespace SparcISA Fault getInterrupt(ThreadContext * tc) { + int hpstate = tc->readMiscReg(MISCREG_HPSTATE); + int pstate = tc->readMiscReg(MISCREG_PSTATE); + bool ie = pstate & PSTATE::ie; + + // THESE ARE IN ORDER OF PRIORITY + // since there are early returns, and the highest + // priority interrupts should get serviced, + // it is v. important that new interrupts are inserted + // in the right order of processing + if (hpstate & HPSTATE::hpriv) { + if (ie) { + if (interrupts[hstick_match]) { + interrupts[hstick_match] = false; + --numPosted; + return new HstickMatch; + } + if (interrupts[interrupt_vector]) { + interrupts[interrupt_vector] = false; + --numPosted; + //HAVEN'T IMPLed THIS YET + return NoFault; + } + } + } else { + + if (interrupts[trap_level_zero]) { + //HAVEN'T IMPLed YET + if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) { + interrupts[trap_level_zero] = false; + --numPosted; + return NoFault; + } + } + if (interrupts[hstick_match]) { + interrupts[hstick_match] = false; + --numPosted; + return new HstickMatch; + } + if (ie) { + if (interrupts[cpu_mondo]) { + interrupts[cpu_mondo] = false; + --numPosted; + return new CpuMondo; + } + if (interrupts[dev_mondo]) { + interrupts[dev_mondo] = false; + --numPosted; + return new DevMondo; + } + if (interrupts[soft_interrupt]) { + int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); + // it seems that interrupt vectors are right in + // the middle of interrupt levels with regard to + // priority, so have to check + if ((il < 6) && + interrupts[interrupt_vector]) { + // may require more details here since there + // may be lots of interrupts embedded in an + // platform interrupt vector + interrupts[interrupt_vector] = false; + --numPosted; + //HAVEN'T IMPLed YET + return NoFault; + } else { + if (il > tc->readMiscReg(MISCREG_PIL)) { + uint64_t si = tc->readMiscReg(MISCREG_SOFTINT); + uint64_t more = si & ~(1 << (il + 1)); + if (!InterruptLevel(more)) { + interrupts[soft_interrupt] = false; + --numPosted; + } + return new InterruptLevelN(il); + } + } + } + if (interrupts[resumable_error]) { + interrupts[resumable_error] = false; + --numPosted; + return new ResumableError; + } + } + } + return NoFault; + + // conditioning the softint interrups - if (tc->readMiscReg(MISCREG_HPSTATE) & hpriv) { + if (tc->readMiscReg(MISCREG_HPSTATE) & HPSTATE::hpriv) { // if running in privileged mode, then pend the interrupt return NoFault; } else { int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); if ((int_level <= tc->readMiscReg(MISCREG_PIL)) || - !(tc->readMiscReg(MISCREG_PSTATE) & ie)) { + !(tc->readMiscReg(MISCREG_PSTATE) & PSTATE::ie)) { // if PIL or no interrupt enabled, then pend the interrupt return NoFault; } else { diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 1f7f65045..c153c2d52 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -38,105 +38,105 @@ using namespace SparcISA; void MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, - ThreadContext *tc) + ThreadContext *tc) { int64_t time; switch (miscReg) { /* Full system only ASRs */ - case MISCREG_SOFTINT: - // Check if we are going to interrupt because of something - setReg(miscReg, val); - tc->getCpuPtr()->checkInterrupts = true; - warn("Writing to softint not really supported, writing: %#x\n", val); - break; + case MISCREG_SOFTINT: + // Check if we are going to interrupt because of something + setReg(miscReg, val); + tc->getCpuPtr()->post_interrupt(soft_interrupt); + warn("Writing to softint not really supported, writing: %#x\n", val); + break; - case MISCREG_SOFTINT_CLR: - return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); - case MISCREG_SOFTINT_SET: - return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); + case MISCREG_SOFTINT_CLR: + return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); + case MISCREG_SOFTINT_SET: + return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); - case MISCREG_TICK_CMPR: - if (tickCompare == NULL) - tickCompare = new TickCompareEvent(this, tc); - setReg(miscReg, val); - if ((tick_cmpr & mask(63)) && tickCompare->scheduled()) - tickCompare->deschedule(); - time = (tick_cmpr & mask(63)) - (tick & mask(63)); - if (!(tick_cmpr & ~mask(63)) && time > 0) - tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); - panic("writing to TICK compare register %#X\n", val); - break; + case MISCREG_TICK_CMPR: + if (tickCompare == NULL) + tickCompare = new TickCompareEvent(this, tc); + setReg(miscReg, val); + if ((tick_cmpr & mask(63)) && tickCompare->scheduled()) + tickCompare->deschedule(); + time = (tick_cmpr & mask(63)) - (tick & mask(63)); + if (!(tick_cmpr & ~mask(63)) && time > 0) + tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); + panic("writing to TICK compare register %#X\n", val); + break; - case MISCREG_STICK_CMPR: - if (sTickCompare == NULL) - sTickCompare = new STickCompareEvent(this, tc); - setReg(miscReg, val); - if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) - sTickCompare->deschedule(); - time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); - if (!(stick_cmpr & ~mask(63)) && time > 0) - sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); - DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); - break; + case MISCREG_STICK_CMPR: + if (sTickCompare == NULL) + sTickCompare = new STickCompareEvent(this, tc); + setReg(miscReg, val); + if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) + sTickCompare->deschedule(); + time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - + tc->getCpuPtr()->instCount(); + if (!(stick_cmpr & ~mask(63)) && time > 0) + sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); + DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); + break; - case MISCREG_PSTATE: - if (val & ie && !(pstate & ie)) { - tc->getCpuPtr()->checkInterrupts = true; - } - setReg(miscReg, val); + case MISCREG_PSTATE: + if (val & ie && !(pstate & ie)) { + tc->getCpuPtr()->checkInterrupts = true; + } + setReg(miscReg, val); - case MISCREG_PIL: - if (val < pil) { - tc->getCpuPtr()->checkInterrupts = true; - } - setReg(miscReg, val); - break; + case MISCREG_PIL: + if (val < pil) { + tc->getCpuPtr()->checkInterrupts = true; + } + setReg(miscReg, val); + break; - case MISCREG_HVER: - panic("Shouldn't be writing HVER\n"); + case MISCREG_HVER: + panic("Shouldn't be writing HVER\n"); - case MISCREG_HTBA: - // clear lower 7 bits on writes. - setReg(miscReg, val & ULL(~0x7FFF)); - break; + case MISCREG_HTBA: + // clear lower 7 bits on writes. + setReg(miscReg, val & ULL(~0x7FFF)); + break; - case MISCREG_QUEUE_CPU_MONDO_HEAD: - case MISCREG_QUEUE_CPU_MONDO_TAIL: - case MISCREG_QUEUE_DEV_MONDO_HEAD: - case MISCREG_QUEUE_DEV_MONDO_TAIL: - case MISCREG_QUEUE_RES_ERROR_HEAD: - case MISCREG_QUEUE_RES_ERROR_TAIL: - case MISCREG_QUEUE_NRES_ERROR_HEAD: - case MISCREG_QUEUE_NRES_ERROR_TAIL: - setReg(miscReg, val); - tc->getCpuPtr()->checkInterrupts = true; - break; + case MISCREG_QUEUE_CPU_MONDO_HEAD: + case MISCREG_QUEUE_CPU_MONDO_TAIL: + case MISCREG_QUEUE_DEV_MONDO_HEAD: + case MISCREG_QUEUE_DEV_MONDO_TAIL: + case MISCREG_QUEUE_RES_ERROR_HEAD: + case MISCREG_QUEUE_RES_ERROR_TAIL: + case MISCREG_QUEUE_NRES_ERROR_HEAD: + case MISCREG_QUEUE_NRES_ERROR_TAIL: + setReg(miscReg, val); + tc->getCpuPtr()->checkInterrupts = true; + break; - case MISCREG_HSTICK_CMPR: - if (hSTickCompare == NULL) - hSTickCompare = new HSTickCompareEvent(this, tc); - setReg(miscReg, val); - if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) - hSTickCompare->deschedule(); - time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); - if (!(hstick_cmpr & ~mask(63)) && time > 0) - hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); - DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); - break; + case MISCREG_HSTICK_CMPR: + if (hSTickCompare == NULL) + hSTickCompare = new HSTickCompareEvent(this, tc); + setReg(miscReg, val); + if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) + hSTickCompare->deschedule(); + time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - + tc->getCpuPtr()->instCount(); + if (!(hstick_cmpr & ~mask(63)) && time > 0) + hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); + DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); + break; - case MISCREG_HPSTATE: - // T1000 spec says impl. dependent val must always be 1 - setReg(miscReg, val | id); - break; - case MISCREG_HTSTATE: - case MISCREG_STRAND_STS_REG: - setReg(miscReg, val); - break; + case MISCREG_HPSTATE: + // T1000 spec says impl. dependent val must always be 1 + setReg(miscReg, val | id); + break; + case MISCREG_HTSTATE: + case MISCREG_STRAND_STS_REG: + setReg(miscReg, val); + break; - default: - panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); + default: + panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); } } @@ -144,7 +144,7 @@ MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) { switch (miscReg) { - /* Privileged registers. */ + /* Privileged registers. */ case MISCREG_QUEUE_CPU_MONDO_HEAD: case MISCREG_QUEUE_CPU_MONDO_TAIL: case MISCREG_QUEUE_DEV_MONDO_HEAD: @@ -174,12 +174,12 @@ MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) } } /* - In Niagra STICK==TICK so this isn't needed - case MISCREG_STICK: - SparcSystem *sys; - sys = dynamic_cast(tc->getSystemPtr()); - assert(sys != NULL); - return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); + In Niagra STICK==TICK so this isn't needed + case MISCREG_STICK: + SparcSystem *sys; + sys = dynamic_cast(tc->getSystemPtr()); + assert(sys != NULL); + return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); */ @@ -198,12 +198,13 @@ MiscRegFile::processSTickCompare(ThreadContext *tc) // more int ticks; ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + tc->getCpuPtr()->instCount(); assert(ticks >= 0 && "stick compare missed interrupt cycle"); if (ticks == 0) { DPRINTF(Timer, "STick compare cycle reached at %#x\n", (stick_cmpr & mask(63))); + tc->getCpuPtr()->post_interrupt(soft_interrupt); tc->getCpuPtr()->checkInterrupts = true; softint |= ULL(1) << 16; } else @@ -218,12 +219,13 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) // more int ticks; ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + tc->getCpuPtr()->instCount(); assert(ticks >= 0 && "hstick compare missed interrupt cycle"); if (ticks == 0) { DPRINTF(Timer, "HSTick compare cycle reached at %#x\n", (stick_cmpr & mask(63))); + tc->getCpuPtr()->post_interrupt(hstick_match); tc->getCpuPtr()->checkInterrupts = true; // Need to do something to cause interrupt to happen here !!! @todo } else diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 31604ad58..b03bc19a5 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -362,6 +362,12 @@ BaseCPU::ProfileEvent::process() schedule(curTick + interval); } +void +BaseCPU::post_interrupt(int int_type) +{ + interrupts.post(int_type); +} + void BaseCPU::post_interrupt(int int_num, int index) { diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 8c6b079da..89c7d9dda 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -102,6 +102,7 @@ class BaseCPU : public MemObject TheISA::Interrupts interrupts; public: + virtual void post_interrupt(int int_type); virtual void post_interrupt(int int_num, int index); virtual void clear_interrupt(int int_num, int index); virtual void clear_interrupts(); From 0d7282d7ab9535a12ce0a0de7e0b3ea36ea9229d Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 8 Jan 2007 20:50:45 -0500 Subject: [PATCH 10/37] pagetable.hh: small fix so ALPHA_FS will build on macs interrupts.hh: small fix for alpha compile src/arch/alpha/interrupts.hh: small fix for alpha compile src/arch/alpha/pagetable.hh: small fix so ALPHA_FS will build on macs --HG-- extra : convert_revision : 5fdbc68caa706d652b51807ac8f6bf58bcf72bdc --- src/arch/alpha/interrupts.hh | 5 +++++ src/arch/alpha/pagetable.hh | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 388ccacde..a522dec6c 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -52,6 +52,11 @@ namespace AlphaISA newInfoSet = false; } + void post(int int_type) + { + // sparc only + } + void post(int int_num, int index) { DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index 7ec4a6a75..c7e1c8923 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -80,7 +80,7 @@ namespace AlphaISA { bool _kre() const { return (entry >> 8) & 0x1; } bool _nomb() const { return (entry >> 7) & 0x1; } int _gh() const { return (entry >> 5) & 0x3; } - bool _asm() const { return (entry >> 4) & 0x1; } + bool _asm_() const { return (entry >> 4) & 0x1; } bool _foe() const { return (entry >> 3) & 0x1; } bool _fow() const { return (entry >> 2) & 0x1; } bool _for() const { return (entry >> 1) & 0x1; } From 7933aade85a61ba745a9dd694b26b7420b7e649c Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 9 Jan 2007 22:16:49 -0500 Subject: [PATCH 11/37] add memory mapped disk device configs/common/FSConfig.py: src/python/m5/objects/T1000.py: add configuration for memory mapped disk src/dev/sparc/SConscript: add memory mapped disk to sconscript --HG-- extra : convert_revision : d8df4a455cf48000042d0ff93a274985f4dbe905 --- configs/common/FSConfig.py | 15 +++- src/dev/sparc/SConscript | 1 + src/dev/sparc/mm_disk.cc | 137 +++++++++++++++++++++++++++++++++ src/dev/sparc/mm_disk.hh | 70 +++++++++++++++++ src/python/m5/objects/T1000.py | 6 ++ 5 files changed, 226 insertions(+), 3 deletions(-) create mode 100644 src/dev/sparc/mm_disk.cc create mode 100644 src/dev/sparc/mm_disk.hh diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index 72742775f..c341b762a 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006 The Regents of The University of Michigan +# Copyright (c) 2006-2007 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -38,6 +38,14 @@ class CowIdeDisk(IdeDisk): def childImage(self, ci): self.image.child.image_file = ci +class CowMmDisk(MmDisk): + image = CowDiskImage(child=RawDiskImage(read_only=True), + read_only=False) + + def childImage(self, ci): + self.image.child.image_file = ci + + class BaseTsunami(Tsunami): ethernet = NSGigE(configdata=NSGigEPciData(), pci_bus=0, pci_dev=1, pci_func=0) @@ -100,8 +108,9 @@ def makeSparcSystem(mem_mode, mdesc = None): self.hypervisor_desc.port = self.membus.port self.partition_desc.port = self.membus.port self.intrctrl = IntrControl() - self.mem_mode = mem_mode - + self.disk0 = CowMmDisk() + self.disk0.childImage(disk('disk.s10hw2')) + self.disk0.pio = self.iobus.port self.reset_bin = binary('reset.bin') self.hypervisor_bin = binary('q.bin') self.openboot_bin = binary('openboot.bin') diff --git a/src/dev/sparc/SConscript b/src/dev/sparc/SConscript index c37294f0c..63f29846a 100644 --- a/src/dev/sparc/SConscript +++ b/src/dev/sparc/SConscript @@ -38,6 +38,7 @@ sources = [] sources += Split(''' t1000.cc + mm_disk.cc ''') # Convert file names to SCons File objects. This takes care of the diff --git a/src/dev/sparc/mm_disk.cc b/src/dev/sparc/mm_disk.cc new file mode 100644 index 000000000..9057c28be --- /dev/null +++ b/src/dev/sparc/mm_disk.cc @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** @file + * This device acts as a disk similar to the memory mapped disk device + * in legion. Any access is translated to an offset in the disk image. + */ + +#include "base/trace.hh" +#include "dev/sparc/mm_disk.hh" +#include "dev/platform.hh" +#include "mem/port.hh" +#include "mem/packet_access.hh" +#include "sim/builder.hh" +#include "sim/byteswap.hh" +#include "sim/system.hh" + +MmDisk::MmDisk(Params *p) + : BasicPioDevice(p), image(p->image), curSector((uint64_t)-1), dirty(false) +{ + memset(&bytes, 0, SectorSize); + pioSize = image->size() * SectorSize; +} + +Tick +MmDisk::read(PacketPtr pkt) +{ + Addr accessAddr; + off_t sector; + off_t bytes_read; + uint16_t *d16; + uint32_t *d32; + uint64_t *d64; + + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + accessAddr = pkt->getAddr() - pioAddr; + + sector = accessAddr / SectorSize; + + if (sector != curSector) { + if (dirty) + bytes_read = image->write(bytes, curSector); + bytes_read = image->read(bytes, sector); + curSector = sector; + } + switch (pkt->getSize()) { + case sizeof(uint8_t): + pkt->set(bytes[accessAddr % SectorSize]); + break; + case sizeof(uint16_t): + d16 = (uint16_t*)bytes + (accessAddr % SectorSize)/2; + pkt->set(htobe(*d16)); + break; + case sizeof(uint32_t): + d32 = (uint32_t*)bytes + (accessAddr % SectorSize)/4; + pkt->set(htobe(*d32)); + break; + case sizeof(uint64_t): + d64 = (uint64_t*)bytes + (accessAddr % SectorSize)/8; + pkt->set(htobe(*d64)); + break; + default: + panic("Invalid access size\n"); + } + + pkt->result = Packet::Success; + return pioDelay; +} + +Tick +MmDisk::write(PacketPtr pkt) +{ + panic("need to implement\n"); +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(MmDisk) + Param pio_addr; + Param pio_latency; + Param pio_size; + SimObjectParam platform; + SimObjectParam system; + SimObjectParam image; +END_DECLARE_SIM_OBJECT_PARAMS(MmDisk) + +BEGIN_INIT_SIM_OBJECT_PARAMS(MmDisk) + + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(pio_size, "Size of address range"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(image, "disk image") + +END_INIT_SIM_OBJECT_PARAMS(MmDisk) + +CREATE_SIM_OBJECT(MmDisk) +{ + MmDisk::Params *p = new MmDisk::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->image = image; + return new MmDisk(p); +} + +REGISTER_SIM_OBJECT("MmDisk", MmDisk) diff --git a/src/dev/sparc/mm_disk.hh b/src/dev/sparc/mm_disk.hh new file mode 100644 index 000000000..0a4626067 --- /dev/null +++ b/src/dev/sparc/mm_disk.hh @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** @file + * This device acts as a disk similar to the memory mapped disk device + * in legion. Any access is translated to an offset in the disk image. + */ + +#ifndef __DEV_SPARC_MM_DISK_HH__ +#define __DEV_SPARC_MM_DISK_HH__ + +#include "base/range.hh" +#include "dev/io_device.hh" +#include "dev/disk_image.hh" + +class MmDisk : public BasicPioDevice +{ + private: + DiskImage *image; + off_t curSector; + bool dirty; + union { + uint8_t bytes[SectorSize]; + uint32_t words[SectorSize/4]; + }; + + public: + struct Params : public BasicPioDevice::Params + { + DiskImage *image; + }; + protected: + const Params *params() const { return (const Params*)_params; } + + public: + MmDisk(Params *p); + + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); +}; + +#endif //__DEV_SPARC_MM_DISK_HH__ + diff --git a/src/python/m5/objects/T1000.py b/src/python/m5/objects/T1000.py index 79195d976..030f4abd8 100644 --- a/src/python/m5/objects/T1000.py +++ b/src/python/m5/objects/T1000.py @@ -5,6 +5,12 @@ from Uart import Uart8250 from Platform import Platform from SimConsole import SimConsole, ConsoleListener + +class MmDisk(BasicPioDevice): + type = 'MmDisk' + image = Param.DiskImage("Disk Image") + pio_addr = 0x1F40000000 + class T1000(Platform): type = 'T1000' system = Param.System(Parent.any, "system") From 28a83c6d1c2673448aaedfb0eb131d6c6604badf Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 9 Jan 2007 22:20:38 -0500 Subject: [PATCH 12/37] quiet/remove some warnings fix implementation of cwp manipulation implement PS0 and PS1 IMMU asis src/arch/sparc/miscregfile.cc: get rid of some warnings fix implementation of setting cwp to saturate cwp since it appears the os sets it to a large value to see how many there actually are src/arch/sparc/tlb.cc: implement PS0 and PS1 IMMU access ASIs src/arch/sparc/ua2005.cc: make warning less verbose --HG-- extra : convert_revision : 442b65dfc41ebc32b2ef0e6b80da94eee3be9cd3 --- src/arch/sparc/miscregfile.cc | 9 +++++---- src/arch/sparc/tlb.cc | 34 ++++++++++++++++++++++++++++++++-- src/arch/sparc/ua2005.cc | 3 ++- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index c58a1fd09..2dde5afd5 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -326,7 +326,6 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) | mbits(tick,63,63); case MISCREG_FPRS: - warn("FPRS register read and FPU stuff not really implemented\n"); // in legion if fp is enabled du and dl are set if (fprs & 0x4) return 0x7; @@ -389,7 +388,6 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) asi = val; break; case MISCREG_FPRS: - warn("FPU not really implemented writing %#X to FPRS\n", val); fprs = val; break; case MISCREG_TICK: @@ -612,6 +610,8 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) void MiscRegFile::setRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { + MiscReg new_val = val; + switch (miscReg) { case MISCREG_STICK: case MISCREG_TICK: @@ -634,7 +634,8 @@ void MiscRegFile::setRegWithEffect(int miscReg, tl = val; return; case MISCREG_CWP: - tc->changeRegFileContext(CONTEXT_CWP, val); + new_val = val > NWindows ? NWindows - 1 : val; + tc->changeRegFileContext(CONTEXT_CWP, new_val); break; case MISCREG_GL: tc->changeRegFileContext(CONTEXT_GLOBALS, val); @@ -671,7 +672,7 @@ void MiscRegFile::setRegWithEffect(int miscReg, panic("Accessing Fullsystem register %s to %#x in SE mode\n", getMiscRegName(miscReg), val); #endif } - setReg(miscReg, val); + setReg(miscReg, new_val); } void MiscRegFile::serialize(std::ostream & os) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 40542a9a6..1cecb4ebb 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -625,13 +625,13 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) return new DataAccessException; } - } else if (hpriv) { + } /*else if (hpriv) {*/ if (asi == ASI_P) { ct = Primary; context = pri_context; goto continueDtbFlow; } - } + //} if (!implicit) { if (AsiIsLittle(asi)) @@ -933,6 +933,36 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4); pkt->set(data); break; + case ASI_IMMU_TSB_PS0_PTR_REG: + temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS); + if (bits(temp,12,0) == 0) { + tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0); + cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG); + } else { + tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0); + cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG); + } + data = mbits(tsbtemp,63,13); + data |= temp >> (9 + bits(cnftemp,2,0) * 3) & + mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4); + pkt->set(data); + break; + case ASI_IMMU_TSB_PS1_PTR_REG: + temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS); + if (bits(temp,12,0) == 0) { + tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1); + cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG); + } else { + tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1); + cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG); + } + data = mbits(tsbtemp,63,13); + if (bits(tsbtemp,12,12)) + data |= ULL(1) << (13+bits(tsbtemp,3,0)); + data |= temp >> (9 + bits(cnftemp,2,0) * 3) & + mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4); + pkt->set(data); + break; default: doMmuReadError: diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 1f7f65045..f03c4da57 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -47,7 +47,8 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, // Check if we are going to interrupt because of something setReg(miscReg, val); tc->getCpuPtr()->checkInterrupts = true; - warn("Writing to softint not really supported, writing: %#x\n", val); + if (val != 0x10000 && val != 0) + warn("Writing to softint not really supported, writing: %#x\n", val); break; case MISCREG_SOFTINT_CLR: From 9d04510869fe66d59a168660925a8387c0fba1b8 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 10 Jan 2007 22:19:13 -0500 Subject: [PATCH 13/37] bug fixes to get us to 145m instructions src/arch/sparc/intregfile.cc: some checks to make sure that the cwp and global register flattening stuff is working. These things have caught a couple of bugs so I think it would be good to keep them around at least for now src/arch/sparc/isa/decoder.isa: fix smul instruction to write Y correctly src/arch/sparc/miscregfile.cc: legion always returns du and dl set, so we need to emulate that for now at least --HG-- extra : convert_revision : 82f9276340888f1e43071c69504486efdcfdb3a8 --- src/arch/sparc/intregfile.cc | 7 +++++++ src/arch/sparc/isa/decoder.isa | 4 ++-- src/arch/sparc/miscregfile.cc | 5 +---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 0a8ac055f..60856d3fa 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -111,6 +111,8 @@ void IntRegFile::setReg(int intReg, const IntReg &val) void IntRegFile::setCWP(int cwp) { int index = ((NWindows - cwp) % NWindows) * 2; + if (index < 0) + panic("Index less than 0. cwp=%d nwin=%d\n", cwp, NWindows); offset[Outputs] = FrameOffset + (index * RegsPerFrame); offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame); offset[Inputs] = FrameOffset + @@ -128,6 +130,11 @@ void IntRegFile::setGlobals(int gl) regView[Globals] = regGlobals[gl]; offset[Globals] = RegGlobalOffset + gl * RegsPerFrame; + + if (regView[Globals] == regView[Inputs] || + regView[Globals] == regView[Locals] || + regView[Globals] == regView[Outputs] ) + panic("Two register arrays set to the same thing!\n"); } void IntRegFile::serialize(std::ostream &os) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index e2bebd987..2e1344a8f 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2006 The Regents of The University of Michigan +// Copyright (c) 2006-2007 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -184,7 +184,7 @@ decode OP default Unknown::unknown() }}); 0x0B: smul({{ Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm13<31:0>; - Y = Rd.sdw; + Y = Rd.sdw<63:32>; }}); 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}}); 0x0D: udivx({{ diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 2dde5afd5..50f510289 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -327,10 +327,7 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) mbits(tick,63,63); case MISCREG_FPRS: // in legion if fp is enabled du and dl are set - if (fprs & 0x4) - return 0x7; - else - return 0; + return fprs | 0x3; case MISCREG_PCR: case MISCREG_PIC: panic("Performance Instrumentation not impl\n"); From d939060ec60da8e11e28a0c9946898a9e651247d Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Thu, 11 Jan 2007 09:18:31 -0500 Subject: [PATCH 14/37] Add Trap Level Zero to interrupts, remove some unreachable code that I forgot to remove last time. --HG-- extra : convert_revision : 74c4c4591be5a66c21077a6fc5f3f60b0ee9bcc1 --- src/arch/sparc/interrupts.hh | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 76bd4c6e2..879cd1825 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -24,8 +24,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black */ #ifndef __ARCH_SPARC_INTERRUPT_HH__ @@ -124,11 +122,10 @@ enum interrupts_t { } else { if (interrupts[trap_level_zero]) { - //HAVEN'T IMPLed YET if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) { interrupts[trap_level_zero] = false; --numPosted; - return NoFault; + return new TrapLevelZero; } } if (interrupts[hstick_match]) { @@ -181,22 +178,6 @@ enum interrupts_t { } } return NoFault; - - - // conditioning the softint interrups - if (tc->readMiscReg(MISCREG_HPSTATE) & HPSTATE::hpriv) { - // if running in privileged mode, then pend the interrupt - return NoFault; - } else { - int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT)); - if ((int_level <= tc->readMiscReg(MISCREG_PIL)) || - !(tc->readMiscReg(MISCREG_PSTATE) & PSTATE::ie)) { - // if PIL or no interrupt enabled, then pend the interrupt - return NoFault; - } else { - return new InterruptLevelN(int_level); - } - } } void updateIntrInfo(ThreadContext * tc) From 9f75c1c58f8352a8625f035c151ebcf6ce95b908 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Thu, 11 Jan 2007 09:29:03 -0500 Subject: [PATCH 15/37] ua2005.cc: i SWEAR i committed this already, but apparently i didnt. ust start using HPSTATE::hpriv, etc. to access bitfields. src/arch/sparc/ua2005.cc: i SWEAR i committed this already, but apparently i didnt. ust start using HPSTATE::hpriv, etc. to access bitfields. --HG-- extra : convert_revision : e66fac9c63088c0fc1a62bd0fac92df305beadff --- src/arch/sparc/ua2005.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index c153c2d52..128402fdd 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -24,8 +24,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Ali Saidi */ #include "arch/sparc/miscregfile.hh" @@ -81,7 +79,7 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, break; case MISCREG_PSTATE: - if (val & ie && !(pstate & ie)) { + if (val & PSTATE::ie && !(pstate & PSTATE::ie)) { tc->getCpuPtr()->checkInterrupts = true; } setReg(miscReg, val); @@ -128,7 +126,7 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, case MISCREG_HPSTATE: // T1000 spec says impl. dependent val must always be 1 - setReg(miscReg, val | id); + setReg(miscReg, val | HPSTATE::id); break; case MISCREG_HTSTATE: case MISCREG_STRAND_STS_REG: From 42535f5f53ad2515cd4b8e617e4a2322aecac547 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Thu, 11 Jan 2007 09:41:34 -0500 Subject: [PATCH 16/37] ua2005.cc: formatting/indentation for case statements src/arch/sparc/ua2005.cc: formatting/indentation for case statements --HG-- extra : convert_revision : aeb7d0274d8d22db3fa56aabbb8ab8f5371a32ff --- src/arch/sparc/ua2005.cc | 188 +++++++++++++++++++-------------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index f03c4da57..4249bb05f 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -38,106 +38,106 @@ using namespace SparcISA; void MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, - ThreadContext *tc) + ThreadContext *tc) { int64_t time; switch (miscReg) { /* Full system only ASRs */ - case MISCREG_SOFTINT: - // Check if we are going to interrupt because of something - setReg(miscReg, val); - tc->getCpuPtr()->checkInterrupts = true; - if (val != 0x10000 && val != 0) - warn("Writing to softint not really supported, writing: %#x\n", val); - break; + case MISCREG_SOFTINT: + // Check if we are going to interrupt because of something + setReg(miscReg, val); + tc->getCpuPtr()->checkInterrupts = true; + if (val != 0x10000 && val != 0) + warn("Writing to softint not really supported, writing: %#x\n", val); + break; - case MISCREG_SOFTINT_CLR: - return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); - case MISCREG_SOFTINT_SET: - return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); + case MISCREG_SOFTINT_CLR: + return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); + case MISCREG_SOFTINT_SET: + return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); - case MISCREG_TICK_CMPR: - if (tickCompare == NULL) - tickCompare = new TickCompareEvent(this, tc); - setReg(miscReg, val); - if ((tick_cmpr & mask(63)) && tickCompare->scheduled()) - tickCompare->deschedule(); - time = (tick_cmpr & mask(63)) - (tick & mask(63)); - if (!(tick_cmpr & ~mask(63)) && time > 0) - tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); - panic("writing to TICK compare register %#X\n", val); - break; + case MISCREG_TICK_CMPR: + if (tickCompare == NULL) + tickCompare = new TickCompareEvent(this, tc); + setReg(miscReg, val); + if ((tick_cmpr & mask(63)) && tickCompare->scheduled()) + tickCompare->deschedule(); + time = (tick_cmpr & mask(63)) - (tick & mask(63)); + if (!(tick_cmpr & ~mask(63)) && time > 0) + tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); + panic("writing to TICK compare register %#X\n", val); + break; - case MISCREG_STICK_CMPR: - if (sTickCompare == NULL) - sTickCompare = new STickCompareEvent(this, tc); - setReg(miscReg, val); - if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) - sTickCompare->deschedule(); - time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); - if (!(stick_cmpr & ~mask(63)) && time > 0) - sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); - DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); - break; + case MISCREG_STICK_CMPR: + if (sTickCompare == NULL) + sTickCompare = new STickCompareEvent(this, tc); + setReg(miscReg, val); + if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) + sTickCompare->deschedule(); + time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - + tc->getCpuPtr()->instCount(); + if (!(stick_cmpr & ~mask(63)) && time > 0) + sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1) + curTick); + DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); + break; - case MISCREG_PSTATE: - if (val & ie && !(pstate & ie)) { - tc->getCpuPtr()->checkInterrupts = true; - } - setReg(miscReg, val); + case MISCREG_PSTATE: + if (val & ie && !(pstate & ie)) { + tc->getCpuPtr()->checkInterrupts = true; + } + setReg(miscReg, val); - case MISCREG_PIL: - if (val < pil) { - tc->getCpuPtr()->checkInterrupts = true; - } - setReg(miscReg, val); - break; + case MISCREG_PIL: + if (val < pil) { + tc->getCpuPtr()->checkInterrupts = true; + } + setReg(miscReg, val); + break; - case MISCREG_HVER: - panic("Shouldn't be writing HVER\n"); + case MISCREG_HVER: + panic("Shouldn't be writing HVER\n"); - case MISCREG_HTBA: - // clear lower 7 bits on writes. - setReg(miscReg, val & ULL(~0x7FFF)); - break; + case MISCREG_HTBA: + // clear lower 7 bits on writes. + setReg(miscReg, val & ULL(~0x7FFF)); + break; - case MISCREG_QUEUE_CPU_MONDO_HEAD: - case MISCREG_QUEUE_CPU_MONDO_TAIL: - case MISCREG_QUEUE_DEV_MONDO_HEAD: - case MISCREG_QUEUE_DEV_MONDO_TAIL: - case MISCREG_QUEUE_RES_ERROR_HEAD: - case MISCREG_QUEUE_RES_ERROR_TAIL: - case MISCREG_QUEUE_NRES_ERROR_HEAD: - case MISCREG_QUEUE_NRES_ERROR_TAIL: - setReg(miscReg, val); - tc->getCpuPtr()->checkInterrupts = true; - break; + case MISCREG_QUEUE_CPU_MONDO_HEAD: + case MISCREG_QUEUE_CPU_MONDO_TAIL: + case MISCREG_QUEUE_DEV_MONDO_HEAD: + case MISCREG_QUEUE_DEV_MONDO_TAIL: + case MISCREG_QUEUE_RES_ERROR_HEAD: + case MISCREG_QUEUE_RES_ERROR_TAIL: + case MISCREG_QUEUE_NRES_ERROR_HEAD: + case MISCREG_QUEUE_NRES_ERROR_TAIL: + setReg(miscReg, val); + tc->getCpuPtr()->checkInterrupts = true; + break; - case MISCREG_HSTICK_CMPR: - if (hSTickCompare == NULL) - hSTickCompare = new HSTickCompareEvent(this, tc); - setReg(miscReg, val); - if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) - hSTickCompare->deschedule(); - time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); - if (!(hstick_cmpr & ~mask(63)) && time > 0) - hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); - DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); - break; + case MISCREG_HSTICK_CMPR: + if (hSTickCompare == NULL) + hSTickCompare = new HSTickCompareEvent(this, tc); + setReg(miscReg, val); + if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) + hSTickCompare->deschedule(); + time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - + tc->getCpuPtr()->instCount(); + if (!(hstick_cmpr & ~mask(63)) && time > 0) + hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->cycles(1)); + DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); + break; - case MISCREG_HPSTATE: - // T1000 spec says impl. dependent val must always be 1 - setReg(miscReg, val | id); - break; - case MISCREG_HTSTATE: - case MISCREG_STRAND_STS_REG: - setReg(miscReg, val); - break; + case MISCREG_HPSTATE: + // T1000 spec says impl. dependent val must always be 1 + setReg(miscReg, val | id); + break; + case MISCREG_HTSTATE: + case MISCREG_STRAND_STS_REG: + setReg(miscReg, val); + break; - default: - panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); + default: + panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); } } @@ -145,7 +145,7 @@ MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) { switch (miscReg) { - /* Privileged registers. */ + /* Privileged registers. */ case MISCREG_QUEUE_CPU_MONDO_HEAD: case MISCREG_QUEUE_CPU_MONDO_TAIL: case MISCREG_QUEUE_DEV_MONDO_HEAD: @@ -175,12 +175,12 @@ MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext * tc) } } /* - In Niagra STICK==TICK so this isn't needed - case MISCREG_STICK: - SparcSystem *sys; - sys = dynamic_cast(tc->getSystemPtr()); - assert(sys != NULL); - return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); + In Niagra STICK==TICK so this isn't needed + case MISCREG_STICK: + SparcSystem *sys; + sys = dynamic_cast(tc->getSystemPtr()); + assert(sys != NULL); + return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); */ @@ -199,7 +199,7 @@ MiscRegFile::processSTickCompare(ThreadContext *tc) // more int ticks; ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + tc->getCpuPtr()->instCount(); assert(ticks >= 0 && "stick compare missed interrupt cycle"); if (ticks == 0) { @@ -219,7 +219,7 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) // more int ticks; ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + tc->getCpuPtr()->instCount(); assert(ticks >= 0 && "hstick compare missed interrupt cycle"); if (ticks == 0) { From ecfd628ecd394f8e7df654ffc7c342d959e12e15 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 16 Jan 2007 19:06:05 -0500 Subject: [PATCH 17/37] Modify ISA and staticInst to support a IsFirstMicroOp flag Increment instruction count on first micro-op instead of last src/arch/sparc/isa/decoder.isa: Implement a twin load for ASI_LDTX_P(0xe2) src/arch/sparc/isa/formats/mem/blockmem.isa: set the new flag IsFirstMicroOp when needed src/cpu/simple/atomic.cc: Increment instruction count on first micro-op instead of last (because if we take a fault on a micro coded instruction it should be counted twice acording to legion) src/cpu/static_inst.hh: Add IsFirstMicroop flag to static insts --HG-- extra : convert_revision : 02bea93d38c03bbafe4570665eb4c01c11caa2fc --- src/arch/sparc/isa/decoder.isa | 3 +++ src/arch/sparc/isa/formats/mem/blockmem.isa | 6 ++++-- src/cpu/simple/atomic.cc | 2 +- src/cpu/static_inst.hh | 2 ++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 2e1344a8f..bd1a44342 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -1079,6 +1079,9 @@ decode OP default Unknown::unknown() //ASI_LDTX_N_L 0x2F: TwinLoad::ldtx_n_l( {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + //ASI_LDTX_P + 0xE2: TwinLoad::ldtx_p( + {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); default: ldtwa({{ uint64_t val = Mem.udw; RdLow = val<31:0>; diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 5d05dad03..32421a75f 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2006 The Regents of The University of Michigan +// Copyright (c) 2006-2007 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -451,6 +451,8 @@ let {{ flag_code = '' if (microPc == 7): flag_code = "flags[IsLastMicroOp] = true;" + elif (microPc == 0): + flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;" else: flag_code = "flags[IsDelayedCommit] = true;" pcedCode = matcher.sub("Frd_%d" % microPc, code) @@ -492,7 +494,7 @@ let {{ flag_code = "flags[IsLastMicroOp] = true;" pcedCode = matcher.sub("RdHigh", code) else: - flag_code = "flags[IsDelayedCommit] = true;" + flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;" pcedCode = matcher.sub("RdLow", code) iop = InstObjParams(name, Name, 'TwinMem', pcedCode, opt_flags, {"ea_code": addrCalcReg, diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 8db864153..3b3536e44 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -497,7 +497,7 @@ AtomicSimpleCPU::tick() // @todo remove me after debugging with legion done if (curStaticInst && (!curStaticInst->isMicroOp() || - curStaticInst->isLastMicroOp())) + curStaticInst->isFirstMicroOp())) instCnt++; if (simulate_stalls) { diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index 523cfae40..5928eea76 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -146,6 +146,7 @@ class StaticInstBase : public RefCounted IsMicroOp, ///< Is a microop IsDelayedCommit, ///< This microop doesn't commit right away IsLastMicroOp, ///< This microop ends a microop sequence + IsFirstMicroOp, ///< This microop begins a microop sequence //This flag doesn't do anything yet IsMicroBranch, ///< This microop branches within the microcode for a macroop @@ -244,6 +245,7 @@ class StaticInstBase : public RefCounted bool isMicroOp() const { return flags[IsMicroOp]; } bool isDelayedCommit() const { return flags[IsDelayedCommit]; } bool isLastMicroOp() const { return flags[IsLastMicroOp]; } + bool isFirstMicroOp() const { return flags[IsFirstMicroOp]; } //This flag doesn't do anything yet bool isMicroBranch() const { return flags[IsMicroBranch]; } //@} From 0584d5bd6c24c66a0d497bba6a3a47d8cdc7a87e Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 16 Jan 2007 19:06:33 -0500 Subject: [PATCH 18/37] In the case of ASI_P or ASI_LDTX_P set primary and skip the other checks --HG-- extra : convert_revision : e7b21c56eadf4603ab03364741b00c9689492423 --- src/arch/sparc/tlb.cc | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 1cecb4ebb..0935cee4e 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -625,13 +625,12 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) return new DataAccessException; } - } /*else if (hpriv) {*/ - if (asi == ASI_P) { - ct = Primary; - context = pri_context; - goto continueDtbFlow; - } - //} + } + if (asi == ASI_P || asi == ASI_LDTX_P) { + ct = Primary; + context = pri_context; + goto continueDtbFlow; + } if (!implicit) { if (AsiIsLittle(asi)) @@ -640,9 +639,6 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) panic("Block ASIs not supported\n"); if (AsiIsNoFault(asi)) panic("No Fault ASIs not supported\n"); - if (write && asi == ASI_LDTX_P) - // block init store (like write hint64) - goto continueDtbFlow; if (!write && asi == ASI_QUAD_LDD) goto continueDtbFlow; From d6c92cdb3c9a8e13fddb58c89f13daac34390522 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 16 Jan 2007 19:08:21 -0500 Subject: [PATCH 19/37] Fix legion lock code a bit so that if we jump out of a micro coded instruction (because of a fault on the first op) we don't lose sync with legion Only print TLB if there is a tlb difference --HG-- extra : convert_revision : f3baf667ca466d6b8efcaccd186ecec14498229d --- src/cpu/exetrace.cc | 54 ++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 6e0bf6d33..87075c1ec 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -59,6 +59,7 @@ using namespace TheISA; #if THE_ISA == SPARC_ISA && FULL_SYSTEM static int diffcount = 0; +static bool wasMicro = false; #endif namespace Trace { @@ -124,6 +125,7 @@ inline void printLevelHeader(ostream & os, int level) void Trace::InstRecord::dump(ostream &outs) { + DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst); if (flags[PRINT_REG_DELTA]) { #if THE_ISA == SPARC_ISA @@ -315,6 +317,24 @@ Trace::InstRecord::dump(ostream &outs) bool diffTlb = false; Addr m5Pc, lgnPc; + // We took a trap on a micro-op... + if (wasMicro && !staticInst->isMicroOp()) + { + // let's skip comparing this cycle + while (!compared) + if (shared_data->flags == OWN_M5) { + shared_data->flags = OWN_LEGION; + compared = true; + } + compared = false; + wasMicro = false; + } + + if (staticInst->isLastMicroOp()) + wasMicro = false; + else if (staticInst->isMicroOp()) + wasMicro = true; + if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { while (!compared) { @@ -587,24 +607,28 @@ Trace::InstRecord::dump(ostream &outs) << endl;*/ } } - printColumnLabels(outs); - char label[8]; - for (int x = 0; x < 64; x++) { - if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) || - thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { - sprintf(label, "I-TLB:%02d", x); - printRegPair(outs, label, thread->getITBPtr()->TteRead(x), shared_data->itb[x]); + if (diffTlb) { + printColumnLabels(outs); + char label[8]; + for (int x = 0; x < 64; x++) { + if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) || + thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { + sprintf(label, "I-TLB:%02d", x); + printRegPair(outs, label, thread->getITBPtr()->TteRead(x), + shared_data->itb[x]); + } } - } - for (int x = 0; x < 64; x++) { - if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) || - thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { - sprintf(label, "D-TLB:%02d", x); - printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), shared_data->dtb[x]); + for (int x = 0; x < 64; x++) { + if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) || + thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { + sprintf(label, "D-TLB:%02d", x); + printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), + shared_data->dtb[x]); + } } + thread->getITBPtr()->dumpAll(); + thread->getDTBPtr()->dumpAll(); } - thread->getITBPtr()->dumpAll(); - thread->getDTBPtr()->dumpAll(); diffcount++; if (diffcount > 2) From 8d75e4ac3f3eb06733e85079e852f64576553519 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 16 Jan 2007 19:09:27 -0500 Subject: [PATCH 20/37] Don't add symbols for loaded files to symbol table since they are pretty much meaningless with all the copying that goes on --HG-- extra : convert_revision : 4d2c1bb72c0344d78d9c3d5958feb3de247102a0 --- src/base/loader/raw_object.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/base/loader/raw_object.cc b/src/base/loader/raw_object.cc index 2a52b0d6e..d002d9005 100644 --- a/src/base/loader/raw_object.cc +++ b/src/base/loader/raw_object.cc @@ -63,19 +63,19 @@ RawObject::RawObject(const std::string &_filename, int _fd, size_t _len, bool RawObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask) { - int fnameStart = filename.rfind('/',filename.size()) + 1; +/* int fnameStart = filename.rfind('/',filename.size()) + 1; int extStart = filename.rfind('.',filename.size()); symtab->insert(text.baseAddr & addrMask, filename.substr(fnameStart, - extStart-fnameStart) + "_start"); + extStart-fnameStart) + "_start");*/ return true; } bool RawObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask) { - int fnameStart = filename.rfind('/',filename.size()) + 1; +/* int fnameStart = filename.rfind('/',filename.size()) + 1; int extStart = filename.rfind('.',filename.size()); symtab->insert(text.baseAddr & addrMask, filename.substr(fnameStart, - extStart-fnameStart) + "_start"); + extStart-fnameStart) + "_start");*/ return true; } From 64528df38d7484591ae27bb2a2252fc1bccd4e9a Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 16 Jan 2007 19:12:33 -0500 Subject: [PATCH 21/37] In the case that we generate a fault (e.g. a tlb miss) on a microcoded instruction set curMacroStaticInst to null This way we'll jump immediately to the handler --HG-- extra : convert_revision : 36218d3a5c2342337e66e1229ea2219533efd41e --- src/cpu/simple/base.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 4e5754bbb..ddccc5a9b 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -437,6 +437,7 @@ void BaseSimpleCPU::advancePC(Fault fault) { if (fault != NoFault) { + curMacroStaticInst = StaticInst::nullStaticInstPtr; fault->invoke(tc); } else { //If we're at the last micro op for this instruction From 8173a05eaf533fd9229c41c106dce0e532c49b0b Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 17 Jan 2007 13:09:26 -0500 Subject: [PATCH 22/37] Implement reading writing of sync fault status register and address register --HG-- extra : convert_revision : c2f60e49683446bcc3afdf911da172de0422b8ad --- src/arch/sparc/tlb.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 0935cee4e..e8b0a933b 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -876,6 +876,9 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS); pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48); break; + case 0x18: + pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_SFSR)); + break; case 0x30: pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS)); break; @@ -889,6 +892,12 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS); pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48); break; + case 0x18: + pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_SFSR)); + break; + case 0x20: + pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_SFAR)); + break; case 0x30: pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS)); break; @@ -1070,6 +1079,9 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) break; case ASI_IMMU: switch (va) { + case 0x18: + tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_SFSR, data); + break; case 0x30: tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS, data); break; @@ -1141,6 +1153,9 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) break; case ASI_DMMU: switch (va) { + case 0x18: + tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_SFSR, data); + break; case 0x30: tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS, data); break; From c8a2d602b15574bbea74ba802415a774c2e4eb38 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 17 Jan 2007 17:59:22 -0500 Subject: [PATCH 23/37] do a linear search for matching tlb entries instead of using map because you could be mapping a larger page that intersects many fix for lookup table to keep it consistant with tlb on a replace of a specific entry --HG-- extra : convert_revision : 5a14fbcdcfc13156c63fa41ddeca474660143b32 --- src/arch/sparc/tlb.cc | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index e8b0a933b..f64bad169 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -81,21 +81,44 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, MapIter i; TlbEntry *new_entry = NULL; - TlbRange tr; +// TlbRange tr; int x; cacheValid = false; - tr.va = va; + /* tr.va = va; tr.size = PTE.size() - 1; tr.contextId = context_id; tr.partitionId = partition_id; tr.real = real; - +*/ DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n", va, PTE.paddr(), partition_id, context_id, (int)real, entry); // Demap any entry that conflicts + for (x = 0; x < size; x++) { + if (tlb[x].range.real == real && + tlb[x].range.partitionId == partition_id && + tlb[x].range.va < va + PTE.size() - 1 && + tlb[x].range.va + tlb[x].range.size >= va && + (real || tlb[x].range.contextId == context_id )) + { + if (tlb[x].valid) { + freeList.push_front(&tlb[x]); + DPRINTF(TLB, "TLB: Conflicting entry %#X , deleting it\n", x); + + tlb[x].valid = false; + if (tlb[x].used) { + tlb[x].used = false; + usedEntries--; + } + lookupTable.erase(tlb[x].range); + } + } + } + + +/* i = lookupTable.find(tr); if (i != lookupTable.end()) { i->second->valid = false; @@ -108,7 +131,7 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, i->second); lookupTable.erase(i); } - +*/ if (entry != -1) { assert(entry < size && entry >= 0); @@ -127,7 +150,6 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, } while (tlb[x].pte.locked()); lastReplaced = x; new_entry = &tlb[x]; - lookupTable.erase(new_entry->range); } /* for (x = 0; x < size; x++) { @@ -142,10 +164,15 @@ insertAllLocked: // Update the last ently if their all locked if (!new_entry) { new_entry = &tlb[size-1]; - lookupTable.erase(new_entry->range); } freeList.remove(new_entry); + if (new_entry->valid && new_entry->used) + usedEntries--; + + lookupTable.erase(new_entry->range); + + DPRINTF(TLB, "Using entry: %#X\n", new_entry); assert(PTE.valid()); @@ -315,10 +342,12 @@ TLB::invalidateAll() cacheValid = false; freeList.clear(); + lookupTable.clear(); for (x = 0; x < size; x++) { if (tlb[x].valid == true) freeList.push_back(&tlb[x]); tlb[x].valid = false; + tlb[x].used = false; } usedEntries = 0; } From ae0d8d16818e49a16a3c2fa0553acf60514934e6 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 17 Jan 2007 18:36:12 -0500 Subject: [PATCH 24/37] Allow ASI_LDTX_REAL --HG-- extra : convert_revision : ba1af012ab8ac61a25058977cb7ec511eb2cf3cb --- src/arch/sparc/tlb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index f64bad169..612345300 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -668,7 +668,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) panic("Block ASIs not supported\n"); if (AsiIsNoFault(asi)) panic("No Fault ASIs not supported\n"); - if (!write && asi == ASI_QUAD_LDD) + if (!write && (asi == ASI_QUAD_LDD || asi == ASI_LDTX_REAL)) goto continueDtbFlow; if (AsiIsTwin(asi)) From f1aeaf7ceb44ea6ef7032048a68c74ecedc7685b Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Fri, 19 Jan 2007 21:33:36 -0500 Subject: [PATCH 25/37] some hstick and hintp changes. src/arch/sparc/interrupts.hh: condition hstick matches on HINTP src/arch/sparc/miscregfile.cc: implement HINTP src/arch/sparc/ua2005.cc: don't post interrupt unless it is enabled. --HG-- extra : convert_revision : f71d1c1d9fd1a898ddafd5a885c3a8d5c75e8ff0 --- src/arch/sparc/interrupts.hh | 22 +++++++++++++++------- src/arch/sparc/miscregfile.cc | 4 ++-- src/arch/sparc/ua2005.cc | 25 ++++++++++++++++--------- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 879cd1825..99ddb4919 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -108,9 +108,11 @@ enum interrupts_t { if (hpstate & HPSTATE::hpriv) { if (ie) { if (interrupts[hstick_match]) { - interrupts[hstick_match] = false; - --numPosted; - return new HstickMatch; + if (tc->readMiscReg(MISCREG_HINTP) & 1) { + interrupts[hstick_match] = false; + --numPosted; + return new HstickMatch; + } } if (interrupts[interrupt_vector]) { interrupts[interrupt_vector] = false; @@ -118,9 +120,13 @@ enum interrupts_t { //HAVEN'T IMPLed THIS YET return NoFault; } + } else { + if (interrupts[hstick_match]) { + return NoFault; + } + } } else { - if (interrupts[trap_level_zero]) { if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) { interrupts[trap_level_zero] = false; @@ -129,9 +135,11 @@ enum interrupts_t { } } if (interrupts[hstick_match]) { - interrupts[hstick_match] = false; - --numPosted; - return new HstickMatch; + if (tc->readMiscReg(MISCREG_HINTP) & 1) { + interrupts[hstick_match] = false; + --numPosted; + return new HstickMatch; + } } if (ie) { if (interrupts[cpu_mondo]) { diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 50f510289..d9fcb0280 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -214,7 +214,7 @@ MiscReg MiscRegFile::readReg(int miscReg) case MISCREG_HTSTATE: return htstate[tl-1]; case MISCREG_HINTP: - panic("HINTP not implemented\n"); + return hintp; case MISCREG_HTBA: return htba; case MISCREG_HVER: @@ -468,7 +468,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) htstate[tl-1] = val; break; case MISCREG_HINTP: - panic("HINTP not implemented\n"); + hintp = val; case MISCREG_HTBA: htba = val; break; diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index b8a891c6d..6220e6dec 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -42,10 +42,7 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, switch (miscReg) { /* Full system only ASRs */ case MISCREG_SOFTINT: - // Check if we are going to interrupt because of something - setReg(miscReg, val); - tc->getCpuPtr()->checkInterrupts = true; - tc->getCpuPtr()->post_interrupt(hstick_match); + setReg(miscReg, val);; if (val != 0x10000 && val != 0) warn("Writing to softint not really supported, writing: %#x\n", val); break; @@ -53,6 +50,8 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, case MISCREG_SOFTINT_CLR: return setRegWithEffect(MISCREG_SOFTINT, ~val & softint, tc); case MISCREG_SOFTINT_SET: + tc->getCpuPtr()->checkInterrupts = true; + tc->getCpuPtr()->post_interrupt(soft_interrupt); return setRegWithEffect(MISCREG_SOFTINT, val | softint, tc); case MISCREG_TICK_CMPR: @@ -96,6 +95,9 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, case MISCREG_HVER: panic("Shouldn't be writing HVER\n"); + case MISCREG_HINTP: + setReg(miscReg, val); + case MISCREG_HTBA: // clear lower 7 bits on writes. setReg(miscReg, val & ULL(~0x7FFF)); @@ -204,9 +206,11 @@ MiscRegFile::processSTickCompare(ThreadContext *tc) if (ticks == 0) { DPRINTF(Timer, "STick compare cycle reached at %#x\n", (stick_cmpr & mask(63))); - tc->getCpuPtr()->post_interrupt(soft_interrupt); - tc->getCpuPtr()->checkInterrupts = true; - softint |= ULL(1) << 16; + if (!(tc->readMiscReg(MISCREG_STICK_CMPR) & (ULL(1) << 63))) { + tc->getCpuPtr()->post_interrupt(soft_interrupt); + tc->getCpuPtr()->checkInterrupts = true; + setRegWithEffect(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc); + } } else sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); } @@ -225,8 +229,11 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) if (ticks == 0) { DPRINTF(Timer, "HSTick compare cycle reached at %#x\n", (stick_cmpr & mask(63))); - tc->getCpuPtr()->post_interrupt(hstick_match); - tc->getCpuPtr()->checkInterrupts = true; + if (!(tc->readMiscReg(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) { + setRegWithEffect(MISCREG_HINTP, 1, tc); + tc->getCpuPtr()->post_interrupt(hstick_match); + tc->getCpuPtr()->checkInterrupts = true; + } // Need to do something to cause interrupt to happen here !!! @todo } else sTickCompare->schedule(ticks * tc->getCpuPtr()->cycles(1) + curTick); From 6e0f1c6062e795201e3ffe1d8a8821e96a6a4b97 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 20 Jan 2007 12:34:00 -0500 Subject: [PATCH 26/37] Spill and Fill handlers are actually n*4 + the start address --HG-- extra : convert_revision : a42f01a84e4b7ba9e6029df50e1612d410a8ba22 --- src/arch/sparc/isa/decoder.isa | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index bd1a44342..2c1b92799 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -471,9 +471,9 @@ decode OP default Unknown::unknown() if(NWindows - 2 - Cansave == 0) { if(Otherwin) - fault = new SpillNOther(Wstate<5:3>); + fault = new SpillNOther(4*Wstate<5:3>); else - fault = new SpillNNormal(Wstate<2:0>); + fault = new SpillNNormal(4*Wstate<2:0>); } }}); 0x2C: decode MOVCC3 @@ -893,9 +893,9 @@ decode OP default Unknown::unknown() if(Canrestore == 0) { if(Otherwin) - fault = new FillNOther(Wstate<5:3>); + fault = new FillNOther(4*Wstate<5:3>); else - fault = new FillNNormal(Wstate<2:0>); + fault = new FillNNormal(4*Wstate<2:0>); } else { @@ -949,9 +949,9 @@ decode OP default Unknown::unknown() if(Cansave == 0) { if(Otherwin) - fault = new SpillNOther(Wstate<5:3>); + fault = new SpillNOther(4*Wstate<5:3>); else - fault = new SpillNNormal(Wstate<2:0>); + fault = new SpillNNormal(4*Wstate<2:0>); //Cwp = (Cwp + 2) % NWindows; } else if(Cleanwin - Canrestore == 0) @@ -975,9 +975,9 @@ decode OP default Unknown::unknown() if(Canrestore == 0) { if(Otherwin) - fault = new FillNOther(Wstate<5:3>); + fault = new FillNOther(4*Wstate<5:3>); else - fault = new FillNNormal(Wstate<2:0>); + fault = new FillNNormal(4*Wstate<2:0>); } else { From ccd67ce44f01aa3d7cd35e9d054e17a2c63ec816 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 20 Jan 2007 12:37:02 -0500 Subject: [PATCH 27/37] Rearange tlb code to remove some duplicate Sparc error register should return ull(0) since it's 64 bits Fix PS1 pointer creation to use the ps1 page size rather than ps0 --HG-- extra : convert_revision : fb4ef4b90270c8db676ffe53578acfa3c244526e --- src/arch/sparc/tlb.cc | 50 ++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 612345300..20a21cf64 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -631,34 +631,32 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) ct = Primary; context = pri_context; } - } else if (!hpriv && !red) { - if (tl > 0 || AsiIsNucleus(asi)) { - ct = Nucleus; - context = 0; - } else if (AsiIsSecondary(asi)) { - ct = Secondary; - context = sec_context; - } else { - context = pri_context; - ct = Primary; //??? - } - + } else { // We need to check for priv level/asi priv - if (!priv && !AsiIsUnPriv(asi)) { + if (!priv && !hpriv && !AsiIsUnPriv(asi)) { // It appears that context should be Nucleus in these cases? writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); return new PrivilegedAction; } - if (priv && AsiIsHPriv(asi)) { + + if (!hpriv && AsiIsHPriv(asi)) { writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi); return new DataAccessException; } - } - if (asi == ASI_P || asi == ASI_LDTX_P) { - ct = Primary; - context = pri_context; - goto continueDtbFlow; + if (AsiIsPrimary(asi)) { + context = pri_context; + ct = Primary; + } else if (AsiIsSecondary(asi)) { + context = sec_context; + ct = Secondary; + } else if (AsiIsNucleus(asi)) { + ct = Nucleus; + context = 0; + } else { // ???? + ct = Primary; + context = pri_context; + } } if (!implicit) { @@ -668,6 +666,10 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) panic("Block ASIs not supported\n"); if (AsiIsNoFault(asi)) panic("No Fault ASIs not supported\n"); + + // These twin ASIs are OK + if (asi == ASI_P || asi == ASI_LDTX_P) + goto continueDtbFlow; if (!write && (asi == ASI_QUAD_LDD || asi == ASI_LDTX_REAL)) goto continueDtbFlow; @@ -687,7 +689,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (AsiIsSparcError(asi)) goto handleSparcErrorRegAccess; - if (!AsiIsReal(asi) && !AsiIsNucleus(asi)) + if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi)) panic("Accessing ASI %#X. Should we?\n", asi); } @@ -707,7 +709,7 @@ continueDtbFlow: } - if ((!lsu_dm && !hpriv) || AsiIsReal(asi)) { + if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) { real = true; context = 0; }; @@ -893,7 +895,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) break; case ASI_SPARC_ERROR_STATUS_REG: warn("returning 0 for SPARC ERROR regsiter read\n"); - pkt->set(0); + pkt->set(ULL(0)); break; case ASI_HYP_SCRATCHPAD: case ASI_SCRATCHPAD: @@ -963,7 +965,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) data = mbits(tsbtemp,63,13); if (bits(tsbtemp,12,12)) data |= ULL(1) << (13+bits(tsbtemp,3,0)); - data |= temp >> (9 + bits(cnftemp,2,0) * 3) & + data |= temp >> (9 + bits(cnftemp,10,8) * 3) & mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4); pkt->set(data); break; @@ -993,7 +995,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) data = mbits(tsbtemp,63,13); if (bits(tsbtemp,12,12)) data |= ULL(1) << (13+bits(tsbtemp,3,0)); - data |= temp >> (9 + bits(cnftemp,2,0) * 3) & + data |= temp >> (9 + bits(cnftemp,10,8) * 3) & mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4); pkt->set(data); break; From 95e4a51c6cf89c5269c758d40dd7952d43d2a3a7 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 20 Jan 2007 23:09:28 -0500 Subject: [PATCH 28/37] fix flushw implementation --HG-- extra : convert_revision : 136b2bddc7cb70cde30e930ad3a13bd56c7162e1 --- src/arch/sparc/isa/decoder.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 2c1b92799..dafdc96f6 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -468,7 +468,7 @@ decode OP default Unknown::unknown() //0x11-0x1F should cause an illegal instruction exception } 0x2B: BasicOperate::flushw({{ - if(NWindows - 2 - Cansave == 0) + if(NWindows - 2 - Cansave != 0) { if(Otherwin) fault = new SpillNOther(4*Wstate<5:3>); From 57d11578cf424f3e1c27d27d63badcdf7d52ba9d Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 20 Jan 2007 23:10:43 -0500 Subject: [PATCH 29/37] atually set all 64 bits of the retun value to 0 --HG-- extra : convert_revision : 77bfdf07a49d41a2392f429fdc632c1461ac504c --- src/arch/sparc/tlb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 20a21cf64..460a9c640 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -895,7 +895,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) break; case ASI_SPARC_ERROR_STATUS_REG: warn("returning 0 for SPARC ERROR regsiter read\n"); - pkt->set(ULL(0)); + pkt->set((uint64_t)0); break; case ASI_HYP_SCRATCHPAD: case ASI_SCRATCHPAD: From d8eeb2e0ff3059a47a0956fbd02234bc32804290 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 20 Jan 2007 23:12:32 -0500 Subject: [PATCH 30/37] fix InterruptLevel code to return the correct level (the bit positition that is set in softint) --HG-- extra : convert_revision : ba0e1f4ec1f74aac64c3f9bb7eb1b771e17b013a --- src/arch/sparc/regfile.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 5d8ac6a17..b36133544 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -189,10 +189,10 @@ int SparcISA::InterruptLevel(uint64_t softint) if (softint & 0x10000 || softint & 0x1) return 14; - int level = 14; - while (level >= 0 && !(1 << (level + 1) & softint)) + int level = 15; + while (level > 0 && !(1 << level & softint)) level--; - if (1 << (level + 1) & softint) + if (1 << level & softint) return level; return 0; } From 3af3610c625d57db3fa75af4f4b24ae72a76595f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sun, 21 Jan 2007 18:04:40 -0500 Subject: [PATCH 31/37] add dumb time of day device --HG-- extra : convert_revision : 52e51ff49f7ed73065f04707ded06dc7254292c4 --- src/dev/sparc/SConscript | 1 + src/dev/sparc/dtod.cc | 115 +++++++++++++++++++++++++++++++++ src/dev/sparc/dtod.hh | 67 +++++++++++++++++++ src/python/m5/objects/T1000.py | 9 +++ 4 files changed, 192 insertions(+) create mode 100644 src/dev/sparc/dtod.cc create mode 100644 src/dev/sparc/dtod.hh diff --git a/src/dev/sparc/SConscript b/src/dev/sparc/SConscript index 63f29846a..44b082b68 100644 --- a/src/dev/sparc/SConscript +++ b/src/dev/sparc/SConscript @@ -37,6 +37,7 @@ Import('env') sources = [] sources += Split(''' + dtod.cc t1000.cc mm_disk.cc ''') diff --git a/src/dev/sparc/dtod.cc b/src/dev/sparc/dtod.cc new file mode 100644 index 000000000..30c7baaf5 --- /dev/null +++ b/src/dev/sparc/dtod.cc @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** @file + * Time of date device implementation + */ +#include + +#include +#include +#include + +#include "base/trace.hh" +#include "dev/sparc/dtod.hh" +#include "dev/platform.hh" +#include "mem/packet_access.hh" +#include "mem/port.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; +using namespace TheISA; + +DumbTOD::DumbTOD(Params *p) + : BasicPioDevice(p), todTime(p->init_time) +{ + pioSize = 0x08; + + struct tm tm; + gmtime_r((time_t*)&todTime, &tm); + DPRINTFN("Real-time clock set to %s\n", asctime(&tm)); + DPRINTFN("Real-time clock set to %d\n", todTime); +} + +Tick +DumbTOD::read(PacketPtr pkt) +{ + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + assert(pkt->getSize() == 8); + + pkt->allocate(); + pkt->set(todTime); + todTime += 1000; + + pkt->result = Packet::Success; + return pioDelay; +} + +Tick +DumbTOD::write(PacketPtr pkt) +{ + panic("Dumb tod device doesn't support writes\n"); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(DumbTOD) + + Param pio_addr; + Param pio_latency; + SimObjectParam platform; + SimObjectParam system; + Param time; + +END_DECLARE_SIM_OBJECT_PARAMS(DumbTOD) + +BEGIN_INIT_SIM_OBJECT_PARAMS(DumbTOD) + + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(time, "System time to use (0 for actual time") + +END_INIT_SIM_OBJECT_PARAMS(DumbTOD) + +CREATE_SIM_OBJECT(DumbTOD) +{ + DumbTOD::Params *p = new DumbTOD::Params; + p->name =getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->init_time = time; + return new DumbTOD(p); +} + +REGISTER_SIM_OBJECT("DumbTOD", DumbTOD) diff --git a/src/dev/sparc/dtod.hh b/src/dev/sparc/dtod.hh new file mode 100644 index 000000000..7d3a9f628 --- /dev/null +++ b/src/dev/sparc/dtod.hh @@ -0,0 +1,67 @@ +/* + * Copyright (c) 206, 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +/** @file + * This device acts as a simple time of date device. It's implemented as a + * simple device register read. + */ + +#ifndef __DEV_SPARC_DTOD_HH__ +#define __DEV_SPARC_DTOD_HH__ + +#include "base/range.hh" +#include "dev/io_device.hh" + + +/** + * DumbTOD simply returns some idea of time when read. Until we finish with + * legion it starts with the start time and increments itself by 1000 each time. + */ +class DumbTOD : public BasicPioDevice +{ + private: + uint64_t todTime; + + public: + struct Params : public BasicPioDevice::Params + { + time_t init_time; + }; + protected: + const Params *params() const { return (const Params *)_params; } + + public: + DumbTOD(Params *p); + + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); +}; + +#endif // __DEV_BADDEV_HH__ diff --git a/src/python/m5/objects/T1000.py b/src/python/m5/objects/T1000.py index 030f4abd8..7b93268ac 100644 --- a/src/python/m5/objects/T1000.py +++ b/src/python/m5/objects/T1000.py @@ -11,6 +11,12 @@ class MmDisk(BasicPioDevice): image = Param.DiskImage("Disk Image") pio_addr = 0x1F40000000 +class DumbTOD(BasicPioDevice): + type = 'DumbTOD' + time = Param.Time('01/01/2009', "System time to use ('Now' for real time)") + pio_addr = 0xfff0c1fff8 + + class T1000(Platform): type = 'T1000' system = Param.System(Parent.any, "system") @@ -64,6 +70,8 @@ class T1000(Platform): warn_access="Accessing SSI -- Unimplemented!") hvuart = Uart8250(pio_addr=0xfff0c2c000) + htod = DumbTOD() + puart0 = Uart8250(pio_addr=0x1f10000000) console = SimConsole(listener = ConsoleListener()) @@ -86,3 +94,4 @@ class T1000(Platform): self.fake_ssi.pio = bus.port self.puart0.pio = bus.port self.hvuart.pio = bus.port + self.htod.pio = bus.port From a7072c19dbd6273920a90a4ec5fa013531316287 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sun, 21 Jan 2007 20:02:41 -0500 Subject: [PATCH 32/37] make sure that page bits of VA on tlb insert are 0 --HG-- extra : convert_revision : f04af884687e9b8631e910cf62cd4a58d035c744 --- src/arch/sparc/tlb.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 460a9c640..61445954f 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -85,6 +85,7 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, int x; cacheValid = false; + va &= ~(PTE.size()-1); /* tr.va = va; tr.size = PTE.size() - 1; tr.contextId = context_id; From e347b49a4edfe89ed5c5352b6c1b93b69ab00134 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 22 Jan 2007 16:11:49 -0500 Subject: [PATCH 33/37] use writeTagAccess() function to unify writing of Tag access registers Fix extracting of secondary context to shove into tag access register properly sign extend va from 59 bits to 63 (SPARC VA hole) --HG-- extra : convert_revision : 5d0c2b4db63338c31b2d29b4bb68f39e1d4f4c7b --- src/arch/sparc/tlb.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 61445954f..e3ac26612 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -415,6 +415,9 @@ TLB::writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct, void TLB::writeTagAccess(ThreadContext *tc, int reg, Addr va, int context) { + DPRINTF(TLB, "TLB: Writing Tag Access: va: %#X ctx: %#X value: %#X\n", + va, context, mbits(va, 63,13) | mbits(context,12,0)); + tc->setMiscRegWithEffect(reg, mbits(va, 63,13) | mbits(context,12,0)); } @@ -537,8 +540,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } if (e == NULL || !e->valid) { - tc->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS, - vaddr & ~BytesInPageMask | context); + writeTagAccess(tc, vaddr, context); if (real) return new InstructionRealTranslationMiss; else @@ -611,7 +613,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) int part_id = bits(tlbdata,15,8); int tl = bits(tlbdata,18,16); int pri_context = bits(tlbdata,47,32); - int sec_context = bits(tlbdata,47,32); + int sec_context = bits(tlbdata,63,48); bool real = false; ContextType ct = Primary; @@ -723,8 +725,7 @@ continueDtbFlow: e = lookup(vaddr, part_id, real, context); if (e == NULL || !e->valid) { - tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, - vaddr & ~BytesInPageMask | context); + writeTagAccess(tc, vaddr, context); DPRINTF(TLB, "TLB: DTB Failed to find matching TLB entry\n"); if (real) return new DataRealTranslationMiss; @@ -1115,6 +1116,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_SFSR, data); break; case 0x30: + sext<59>(bits(data, 59,0)); tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS, data); break; default: @@ -1189,6 +1191,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_SFSR, data); break; case 0x30: + sext<59>(bits(data, 59,0)); tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS, data); break; case 0x80: From 5c1d631f36bc0d1a99875fb54b92a5df510fa9e3 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 22 Jan 2007 16:14:06 -0500 Subject: [PATCH 34/37] check if an executable is dynamic and die if it is Only implemented for ELf. Someone might want to implement it for ecoff and some point src/base/loader/elf_object.cc: src/base/loader/elf_object.hh: src/base/loader/object_file.cc: src/base/loader/object_file.hh: add a function to check if an executable is dynamic src/sim/process.cc: check if an executable is dynamic and die if it is --HG-- extra : convert_revision : 830b1b50b08a5abaf895ce6251bbc702c986eebf --- src/base/loader/elf_object.cc | 38 ++++++++++++++++++++++++++++++++++ src/base/loader/elf_object.hh | 2 ++ src/base/loader/object_file.cc | 6 ++++++ src/base/loader/object_file.hh | 2 ++ src/sim/process.cc | 5 +++++ 5 files changed, 53 insertions(+) diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 7339507f6..89a5d4512 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -340,3 +340,41 @@ ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask) { return loadSomeSymbols(symtab, STB_LOCAL); } + +bool +ElfObject::isDynamic() +{ + Elf *elf; + int sec_idx = 1; // there is a 0 but it is nothing, go figure + Elf_Scn *section; + GElf_Shdr shdr; + + GElf_Ehdr ehdr; + + // check that header matches library version + if (elf_version(EV_CURRENT) == EV_NONE) + panic("wrong elf version number!"); + + // get a pointer to elf structure + elf = elf_memory((char*)fileData,len); + assert(elf != NULL); + + // Check that we actually have a elf file + if (gelf_getehdr(elf, &ehdr) ==0) { + panic("Not ELF, shouldn't be here"); + } + + // Get the first section + section = elf_getscn(elf, sec_idx); + + // While there are no more sections + while (section != NULL) { + gelf_getshdr(section, &shdr); + if (!strcmp(".dynamic", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) + return true; + section = elf_getscn(elf, ++sec_idx); + } // while sections + return false; +} + + diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh index fb728b3c5..d909140f3 100644 --- a/src/base/loader/elf_object.hh +++ b/src/base/loader/elf_object.hh @@ -58,6 +58,8 @@ class ElfObject : public ObjectFile virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = std::numeric_limits::max()); + virtual bool isDynamic(); + static ObjectFile *tryFile(const std::string &fname, int fd, size_t len, uint8_t *data); Addr programHeaderTable() {return _programHeaderTable;} diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc index ad2cd34ba..da5aa9552 100644 --- a/src/base/loader/object_file.cc +++ b/src/base/loader/object_file.cc @@ -150,3 +150,9 @@ createObjectFile(const string &fname, bool raw) munmap(fileData, len); return NULL; } + +bool +ObjectFile::isDynamic() +{ + return false; +} diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh index 6e98332c5..18e6482be 100644 --- a/src/base/loader/object_file.hh +++ b/src/base/loader/object_file.hh @@ -83,6 +83,8 @@ class ObjectFile virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = std::numeric_limits::max()) = 0; + virtual bool isDynamic(); + Arch getArch() const { return arch; } OpSys getOpSys() const { return opSys; } diff --git a/src/sim/process.cc b/src/sim/process.cc index b43fa7d00..63ff33969 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -440,6 +440,11 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd, fatal("Can't load object file %s", executable); } + if (objFile->isDynamic()) + fatal("Object file is a dynamic executable however only static " + "executables are supported!\n Please recompile your " + "executable as a static binary and try again.\n"); + #if THE_ISA == ALPHA_ISA if (objFile->getArch() != ObjectFile::Alpha) fatal("Object file architecture does not match compiled ISA (Alpha)."); From 3011fc63111735bc3de000f121661ee60631cb4c Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 22 Jan 2007 21:45:29 -0500 Subject: [PATCH 35/37] we decided to check for .interp instead of .dynamic --HG-- extra : convert_revision : 4f5c7f9c7653e1e9ebbd488c07426d9f944bb25f --- src/base/loader/elf_object.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 89a5d4512..d59affe85 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -370,7 +370,7 @@ ElfObject::isDynamic() // While there are no more sections while (section != NULL) { gelf_getshdr(section, &shdr); - if (!strcmp(".dynamic", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) + if (!strcmp(".interp", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) return true; section = elf_getscn(elf, ++sec_idx); } // while sections From 5f662d451ee8311c0f42eaf6ed6415b4d0f0f473 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 22 Jan 2007 21:55:43 -0500 Subject: [PATCH 36/37] clean up fault code a little bit simplify and make complete some asi checks implement all the twin asis and remove panic checks on their use soft int is supported, so we don't need to print writes to it src/arch/sparc/asi.cc: make AsiIsLittle() be all the little asis. Speed up AsiIsTwin() a bit src/arch/sparc/faults.cc: clean up the do*Fault code.... Make it work like legion, in particular pstate.priv is left alone, not set to 0 like the spec says src/arch/sparc/isa/decoder.isa: implement some more twin ASIs src/arch/sparc/tlb.cc: All the twin asis are implemented, no need to say their not supported anymore src/arch/sparc/ua2005.cc: softint is supported now, no more need to --HG-- extra : convert_revision : aef2a1b93719235edff830a17a8ec52f23ec9f8b --- src/arch/sparc/asi.cc | 27 +++++++-------- src/arch/sparc/faults.cc | 63 ++++++++-------------------------- src/arch/sparc/isa/decoder.isa | 9 +++++ src/arch/sparc/tlb.cc | 14 ++------ src/arch/sparc/ua2005.cc | 2 -- 5 files changed, 39 insertions(+), 76 deletions(-) diff --git a/src/arch/sparc/asi.cc b/src/arch/sparc/asi.cc index a9a778ff6..3d553955f 100644 --- a/src/arch/sparc/asi.cc +++ b/src/arch/sparc/asi.cc @@ -179,26 +179,23 @@ namespace SparcISA (asi == ASI_LDTX_PL) || (asi == ASI_LDTX_SL) || (asi == ASI_BLK_PL) || - (asi == ASI_BLK_SL); + (asi == ASI_BLK_SL) || + (asi == ASI_LTX_L); } bool AsiIsTwin(ASI asi) { return - (asi == ASI_QUAD_LDD) || - (asi == ASI_LDTX_AIUP) || - (asi == ASI_LDTX_AIUS) || - (asi == ASI_LDTX_REAL) || - (asi == ASI_LDTX_N) || - (asi == ASI_LDTX_AIUP_L) || - (asi == ASI_LDTX_AIUS_L) || - (asi == ASI_LDTX_REAL_L) || - (asi == ASI_LDTX_NL) || - (asi == ASI_LDTX_P) || - (asi == ASI_LDTX_S) || - (asi == ASI_LDTX_PL) || - (asi == ASI_LDTX_SL) || - (asi == ASI_LTX_L); + (asi >= ASI_LDTX_AIUP && + asi <= ASI_LDTX_N && + asi != ASI_QUEUE) || + (asi >= ASI_LDTX_AIUP_L && + asi <= ASI_LDTX_NL && + asi != 0x2D) || + asi == ASI_LDTX_P || + asi == ASI_LDTX_S || + asi == ASI_LDTX_PL || + asi == ASI_LDTX_SL; } bool AsiIsPartialStore(ASI asi) diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index a74eebafa..b465e52d2 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -340,22 +340,8 @@ void doREDFault(ThreadContext *tc, TrapType tt) //Update GL tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxGL)); - //set PSTATE.mm to 00 - //set PSTATE.pef to 1 - PSTATE |= (1 << 4); - //set PSTATE.am to 0 - PSTATE &= ~(1 << 3); -/* //set PSTATE.priv to 0 - PSTATE &= ~(1 << 2);*/ - //set PSTATE.ie to 0 - //PSTATE.priv is set to 1 here. The manual says it should be 0, but - //Legion sets it to 1. - PSTATE |= (1 << 2); - //set PSTATE.cle to 0 - PSTATE &= ~(1 << 9); - //PSTATE.tle is unchanged - //XXX Where is the tct bit? - //set PSTATE.tct to 0 + PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit + PSTATE |= (1 << 4); //set PSTATE.pef to 1 tc->setMiscReg(MISCREG_PSTATE, PSTATE); //set HPSTATE.red to 1 @@ -442,46 +428,27 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxGL)); //PSTATE.mm is unchanged - //PSTATE.pef = whether or not an fpu is present - //XXX We'll say there's one present, even though there aren't - //implementations for a decent number of the instructions - PSTATE |= (1 << 4); - //PSTATE.am = 0 - PSTATE &= ~(1 << 3); - if (!gotoHpriv) - { - //PSTATE.priv = 1 - PSTATE |= (1 << 2); - //PSTATE.cle = PSTATE.tle - replaceBits(PSTATE, 9, 9, PSTATE >> 8); - } - else - { - //PSTATE.priv = 0 - //PSTATE.priv is set to 1 here. The manual says it should be 0, but - //Legion sets it to 1. - PSTATE |= (1 << 2); - //PSTATE.cle = 0 - PSTATE &= ~(1 << 9); - } - //PSTATE.ie = 0 - PSTATE &= ~(1 << 1); + PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present + PSTATE &= ~(1 << 3); //PSTATE.am = 0 + PSTATE &= ~(1 << 1); //PSTATE.ie = 0 //PSTATE.tle is unchanged //PSTATE.tct = 0 - //XXX Where exactly is this field? - tc->setMiscReg(MISCREG_PSTATE, PSTATE); if (gotoHpriv) { - //HPSTATE.red = 0 - HPSTATE &= ~(1 << 5); - //HPSTATE.hpriv = 1 - HPSTATE |= (1 << 2); - //HPSTATE.ibe = 0 - HPSTATE &= ~(1 << 10); + PSTATE &= ~(1 << 9); // PSTATE.cle = 0 + //The manual says PSTATE.priv should be 0, but Legion leaves it alone + HPSTATE &= ~(1 << 5); //HPSTATE.red = 0 + HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1 + HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0 //HPSTATE.tlz is unchanged tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); + } else { // we are going to priv + PSTATE |= (1 << 2); //PSTATE.priv = 1 + replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle } + tc->setMiscReg(MISCREG_PSTATE, PSTATE); + bool changedCWP = true; if (tt == 0x24) diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index dafdc96f6..175866eba 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -1061,6 +1061,12 @@ decode OP default Unknown::unknown() 0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}}); 0x12: lduha({{Rd = Mem.uhw;}}, {{EXT_ASI}}); 0x13: decode EXT_ASI { + //ASI_LDTD_AIUP + 0x22: TwinLoad::ldtx_aiup( + {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + //ASI_LDTD_AIUS + 0x23: TwinLoad::ldtx_aius( + {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); //ASI_QUAD_LDD 0x24: TwinLoad::ldtx_quad_ldd( {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); @@ -1082,6 +1088,9 @@ decode OP default Unknown::unknown() //ASI_LDTX_P 0xE2: TwinLoad::ldtx_p( {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); + //ASI_LDTX_S + 0xE3: TwinLoad::ldtx_s( + {{RdTwin.udw = Mem.udw}}, {{EXT_ASI}}); default: ldtwa({{ uint64_t val = Mem.udw; RdLow = val<31:0>; diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index e3ac26612..1a2ec6eac 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -662,7 +662,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) } } - if (!implicit) { + if (!implicit && asi != ASI_P && asi != ASI_S) { if (AsiIsLittle(asi)) panic("Little Endian ASIs not supported\n"); if (AsiIsBlock(asi)) @@ -670,14 +670,6 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (AsiIsNoFault(asi)) panic("No Fault ASIs not supported\n"); - // These twin ASIs are OK - if (asi == ASI_P || asi == ASI_LDTX_P) - goto continueDtbFlow; - if (!write && (asi == ASI_QUAD_LDD || asi == ASI_LDTX_REAL)) - goto continueDtbFlow; - - if (AsiIsTwin(asi)) - panic("Twin ASIs not supported\n"); if (AsiIsPartialStore(asi)) panic("Partial Store ASIs not supported\n"); if (AsiIsInterrupt(asi)) @@ -692,11 +684,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (AsiIsSparcError(asi)) goto handleSparcErrorRegAccess; - if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi)) + if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi) && + !AsiIsTwin(asi)) panic("Accessing ASI %#X. Should we?\n", asi); } -continueDtbFlow: // If the asi is unaligned trap if (vaddr & size-1) { writeSfr(tc, vaddr, false, ct, false, OtherFault, asi); diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 6220e6dec..00a44275c 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -43,8 +43,6 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, /* Full system only ASRs */ case MISCREG_SOFTINT: setReg(miscReg, val);; - if (val != 0x10000 && val != 0) - warn("Writing to softint not really supported, writing: %#x\n", val); break; case MISCREG_SOFTINT_CLR: From 60eaa03d72a13863596e64343d7407af1cab51c5 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 22 Jan 2007 21:57:01 -0500 Subject: [PATCH 37/37] fix compiling on x86/Solaris --HG-- extra : convert_revision : f7d21fc277dd7172c244d83fb012883dc8b67895 --- src/sim/byteswap.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sim/byteswap.hh b/src/sim/byteswap.hh index 7b1ae701e..4ac1ee711 100644 --- a/src/sim/byteswap.hh +++ b/src/sim/byteswap.hh @@ -130,7 +130,7 @@ template static inline T letobe(T value) {return swap_byte(value);} //For conversions not involving the guest system, we can define the functions //conditionally based on the BYTE_ORDER macro and outside of the namespaces -#if defined(_BIG_ENDIAN) || BYTE_ORDER == BIG_ENDIAN +#if defined(_BIG_ENDIAN) || !defined(_LITTLE_ENDIAN) && BYTE_ORDER == BIG_ENDIAN template static inline T htole(T value) {return swap_byte(value);} template static inline T letoh(T value) {return swap_byte(value);} template static inline T htobe(T value) {return value;}