diff options
-rw-r--r-- | cpu/simple_cpu/simple_cpu.cc | 29 | ||||
-rw-r--r-- | python/m5/config.py | 131 | ||||
-rw-r--r-- | python/m5/objects/AlphaConsole.mpy | 6 | ||||
-rw-r--r-- | python/m5/objects/BaseCPU.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/BaseSystem.mpy | 4 | ||||
-rw-r--r-- | python/m5/objects/Device.mpy | 4 | ||||
-rw-r--r-- | python/m5/objects/Ethernet.mpy | 6 | ||||
-rw-r--r-- | python/m5/objects/Ide.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/IntrControl.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/Pci.mpy | 4 | ||||
-rw-r--r-- | python/m5/objects/PhysicalMemory.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/Platform.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/SimConsole.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/SimpleDisk.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/Tsunami.mpy | 8 | ||||
-rw-r--r-- | python/m5/objects/Uart.mpy | 2 | ||||
-rw-r--r-- | python/m5/smartdict.py | 6 | ||||
-rw-r--r-- | sim/sim_object.cc | 19 | ||||
-rw-r--r-- | sim/sim_object.hh | 17 |
19 files changed, 161 insertions, 89 deletions
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 86aeab7d7..6a95a52c2 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -393,13 +393,11 @@ template <class T> Fault SimpleCPU::read(Addr addr, T &data, unsigned flags) { - if (status() == DcacheMissStall) { + if (status() == DcacheMissStall || status() == DcacheMissSwitch) { Fault fault = xc->read(memReq,data); if (traceData) { traceData->setAddr(addr); - if (fault == No_Fault) - traceData->setData(data); } return fault; } @@ -428,21 +426,11 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) // do functional access fault = xc->read(memReq, data); - if (traceData) { - traceData->setAddr(addr); - if (fault == No_Fault) - traceData->setData(data); - } } } else if(fault == No_Fault) { // do functional access fault = xc->read(memReq, data); - if (traceData) { - traceData->setAddr(addr); - if (fault == No_Fault) - traceData->setData(data); - } } if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) @@ -498,11 +486,6 @@ template <class T> Fault SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { - if (traceData) { - traceData->setAddr(addr); - traceData->setData(data); - } - memReq->reset(addr, sizeof(T), flags); // translate to physical address @@ -605,6 +588,8 @@ SimpleCPU::processCacheCompletion() case DcacheMissStall: if (memReq->cmd.isRead()) { curStaticInst->execute(this,traceData); + if (traceData) + traceData->finalize(); } dcacheStallCycles += curTick - lastDcacheStall; _status = Running; @@ -613,6 +598,8 @@ SimpleCPU::processCacheCompletion() case DcacheMissSwitch: if (memReq->cmd.isRead()) { curStaticInst->execute(this,traceData); + if (traceData) + traceData->finalize(); } _status = SwitchedOut; sampler->signalSwitched(); @@ -785,8 +772,12 @@ SimpleCPU::tick() comLoadEventQueue[0]->serviceEvents(numLoad); } - if (traceData) + // If we have a dcache miss, then we can't finialize the instruction + // trace yet because we want to populate it with the data later + if (traceData && + !(status() == DcacheMissStall && memReq->cmd.isRead())) { traceData->finalize(); + } traceFunctions(xc->regs.pc); diff --git a/python/m5/config.py b/python/m5/config.py index 182acf393..e6ad5a0ba 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -139,25 +139,90 @@ class Singleton(type): ##################################################################### class Proxy(object): - def __init__(self, path = ()): + def __init__(self, path): self._object = None - self._path = path + if path == 'any': + self._path = None + else: + # path is a list of (attr,index) tuples + self._path = [(path,None)] + self._index = None + self._multiplier = None def __getattr__(self, attr): - return Proxy(self._path + (attr, )) + if attr == '__bases__': + return super(Proxy, self).__getattr__(self, attr) + self._path.append((attr,None)) + return self def __setattr__(self, attr, value): if not attr.startswith('_'): raise AttributeError, 'cannot set attribute %s' % attr super(Proxy, self).__setattr__(attr, value) - def _convert(self): - obj = self._object - for attr in self._path: - obj = obj.__getattribute__(attr) + # support indexing on proxies (e.g., parent.cpu[0]) + def __getitem__(self, key): + if not isinstance(key, int): + raise TypeError, "Proxy object requires integer index" + if self._path == None: + raise IndexError, "Index applied to 'any' proxy" + # replace index portion of last path element with new index + self._path[-1] = (self._path[-1][0], key) + return self + + # support multiplying proxies by constants + def __mul__(self, other): + if not isinstance(other, int): + raise TypeError, "Proxy multiplier must be integer" + if self._multiplier == None: + self._multiplier = other + else: + # support chained multipliers + self._multiplier *= other + return self + + def _mulcheck(self, result): + if self._multiplier == None: + return result + if not isinstance(result, int): + raise TypeError, "Proxy with multiplier resolves to " \ + "non-integer value" + return result * self._multiplier + + def unproxy(self, base, ptype): + obj = base + done = False + while not done: + if obj is None: + raise AttributeError, \ + 'Parent of %s type %s not found at path %s' \ + % (base.name, ptype, self._path) + found, done = obj.find(ptype, self._path) + if isinstance(found, Proxy): + done = False + obj = obj.parent + + return self._mulcheck(found) + + def getindex(obj, index): + if index == None: + return obj + try: + obj = obj[index] + except TypeError: + if index != 0: + raise + # if index is 0 and item is not subscriptable, just + # use item itself (so cpu[0] works on uniprocessors) return obj + getindex = staticmethod(getindex) + +class ProxyFactory(object): + def __getattr__(self, attr): + return Proxy(attr) -Super = Proxy() +# global object for handling parent.foo proxies +parent = ProxyFactory() def isSubClass(value, cls): try: @@ -643,50 +708,40 @@ class Node(object): if issubclass(child.realtype, realtype): if obj is not None: raise AttributeError, \ - 'Super matched more than one: %s %s' % \ + 'parent.any matched more than one: %s %s' % \ (obj.path, child.path) obj = child return obj, obj is not None try: obj = self - for node in path[:-1]: - obj = obj.child_names[node] + for (node,index) in path[:-1]: + if obj.child_names.has_key(node): + obj = obj.child_names[node] + else: + obj = obj.top_child_names[node] + obj = Proxy.getindex(obj, index) - last = path[-1] + (last,index) = path[-1] if obj.child_names.has_key(last): value = obj.child_names[last] - if issubclass(value.realtype, realtype): - return value, True + return Proxy.getindex(value, index), True + elif obj.top_child_names.has_key(last): + value = obj.top_child_names[last] + return Proxy.getindex(value, index), True elif obj.param_names.has_key(last): value = obj.param_names[last] realtype._convert(value.value) - return value.value, True + return Proxy.getindex(value.value, index), True except KeyError: pass return None, False - def unproxy(self, ptype, value): - if not isinstance(value, Proxy): - return value - - if value is None: - raise AttributeError, 'Error while fixing up %s' % self.path - - obj = self - done = False - while not done: - if obj is None: - raise AttributeError, \ - 'Parent of %s type %s not found at path %s' \ - % (self.name, ptype, value._path) - found, done = obj.find(ptype, value._path) - if isinstance(found, Proxy): - done = False - obj = obj.parent - - return found + def unproxy(self, param, ptype): + if not isinstance(param, Proxy): + return param + return param.unproxy(self, ptype) def fixup(self): self.all[self.path] = self @@ -697,9 +752,9 @@ class Node(object): try: if isinstance(pval, (list, tuple)): - param.value = [ self.unproxy(ptype, pv) for pv in pval ] + param.value = [ self.unproxy(pv, ptype) for pv in pval ] else: - param.value = self.unproxy(ptype, pval) + param.value = self.unproxy(pval, ptype) except: print 'Error while fixing up %s:%s' % (self.path, param.name) raise @@ -1337,7 +1392,7 @@ class SimObject(ConfigNode, ParamType): # 'from config import *' is invoked. Try to keep this reasonably # short to avoid polluting other namespaces. __all__ = ['ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', - 'Super', 'Enum', + 'parent', 'Enum', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64', 'Counter', 'Addr', 'Tick', 'Percent', diff --git a/python/m5/objects/AlphaConsole.mpy b/python/m5/objects/AlphaConsole.mpy index 79918a01e..63aea5b7d 100644 --- a/python/m5/objects/AlphaConsole.mpy +++ b/python/m5/objects/AlphaConsole.mpy @@ -2,8 +2,8 @@ from Device import PioDevice simobj AlphaConsole(PioDevice): type = 'AlphaConsole' - cpu = Param.BaseCPU(Super, "Processor") + cpu = Param.BaseCPU(parent.any, "Processor") disk = Param.SimpleDisk("Simple Disk") num_cpus = Param.Int(1, "Number of CPUs") - sim_console = Param.SimConsole(Super, "The Simulator Console") - system = Param.BaseSystem(Super, "system object") + sim_console = Param.SimConsole(parent.any, "The Simulator Console") + system = Param.BaseSystem(parent.any, "system object") diff --git a/python/m5/objects/BaseCPU.mpy b/python/m5/objects/BaseCPU.mpy index 5d8305d88..d84e30e53 100644 --- a/python/m5/objects/BaseCPU.mpy +++ b/python/m5/objects/BaseCPU.mpy @@ -8,7 +8,7 @@ simobj BaseCPU(SimObject): dtb = Param.AlphaDTB("Data TLB") itb = Param.AlphaITB("Instruction TLB") mem = Param.FunctionalMemory("memory") - system = Param.BaseSystem(Super, "system object") + system = Param.BaseSystem(parent.any, "system object") else: workload = VectorParam.Process("processes to run") diff --git a/python/m5/objects/BaseSystem.mpy b/python/m5/objects/BaseSystem.mpy index 1cbdf4e99..450b6a58e 100644 --- a/python/m5/objects/BaseSystem.mpy +++ b/python/m5/objects/BaseSystem.mpy @@ -1,8 +1,8 @@ simobj BaseSystem(SimObject): type = 'BaseSystem' abstract = True - memctrl = Param.MemoryController(Super, "memory controller") - physmem = Param.PhysicalMemory(Super, "phsyical memory") + memctrl = Param.MemoryController(parent.any, "memory controller") + physmem = Param.PhysicalMemory(parent.any, "phsyical memory") kernel = Param.String("file that contains the kernel code") console = Param.String("file that contains the console code") pal = Param.String("file that contains palcode") diff --git a/python/m5/objects/Device.mpy b/python/m5/objects/Device.mpy index 47f8db1cb..a0d02a647 100644 --- a/python/m5/objects/Device.mpy +++ b/python/m5/objects/Device.mpy @@ -14,7 +14,7 @@ simobj FooPioDevice(FunctionalMemory): type = 'PioDevice' abstract = True addr = Param.Addr("Device Address") - mmu = Param.MemoryController(Super, "Memory Controller") + mmu = Param.MemoryController(parent.any, "Memory Controller") io_bus = Param.Bus(NULL, "The IO Bus to attach to") pio_latency = Param.Tick(1, "Programmed IO latency in bus cycles") @@ -25,7 +25,7 @@ simobj FooDmaDevice(FooPioDevice): simobj PioDevice(FooPioDevice): type = 'PioDevice' abstract = True - platform = Param.Platform(Super, "Platform") + platform = Param.Platform(parent.any, "Platform") simobj DmaDevice(PioDevice): type = 'DmaDevice' diff --git a/python/m5/objects/Ethernet.mpy b/python/m5/objects/Ethernet.mpy index 088df4b93..cd251f36d 100644 --- a/python/m5/objects/Ethernet.mpy +++ b/python/m5/objects/Ethernet.mpy @@ -49,8 +49,8 @@ simobj EtherDev(DmaDevice): intr_delay = Param.Tick(0, "Interrupt Delay in microseconds") payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload") - physmem = Param.PhysicalMemory(Super, "Physical Memory") - tlaser = Param.Turbolaser(Super, "Turbolaser") + physmem = Param.PhysicalMemory(parent.any, "Physical Memory") + tlaser = Param.Turbolaser(parent.any, "Turbolaser") simobj NSGigE(PciDevice): type = 'NSGigE' @@ -73,7 +73,7 @@ simobj NSGigE(PciDevice): intr_delay = Param.Tick(0, "Interrupt Delay in microseconds") payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload") - physmem = Param.PhysicalMemory(Super, "Physical Memory") + physmem = Param.PhysicalMemory(parent.any, "Physical Memory") simobj EtherDevInt(EtherInt): type = 'EtherDevInt' diff --git a/python/m5/objects/Ide.mpy b/python/m5/objects/Ide.mpy index ce760ad96..786109efa 100644 --- a/python/m5/objects/Ide.mpy +++ b/python/m5/objects/Ide.mpy @@ -7,7 +7,7 @@ simobj IdeDisk(SimObject): delay = Param.Tick(1, "Fixed disk delay in microseconds") driveID = Param.IdeID('master', "Drive ID") image = Param.DiskImage("Disk image") - physmem = Param.PhysicalMemory(Super, "Physical memory") + physmem = Param.PhysicalMemory(parent.any, "Physical memory") simobj IdeController(PciDevice): type = 'IdeController' diff --git a/python/m5/objects/IntrControl.mpy b/python/m5/objects/IntrControl.mpy index 1ef5a17ee..144be0fd4 100644 --- a/python/m5/objects/IntrControl.mpy +++ b/python/m5/objects/IntrControl.mpy @@ -1,3 +1,3 @@ simobj IntrControl(SimObject): type = 'IntrControl' - cpu = Param.BaseCPU(Super, "the cpu") + cpu = Param.BaseCPU(parent.any, "the cpu") diff --git a/python/m5/objects/Pci.mpy b/python/m5/objects/Pci.mpy index f7c6674f7..b9b3e5a95 100644 --- a/python/m5/objects/Pci.mpy +++ b/python/m5/objects/Pci.mpy @@ -47,5 +47,5 @@ simobj PciDevice(DmaDevice): pci_bus = Param.Int("PCI bus") pci_dev = Param.Int("PCI device number") pci_func = Param.Int("PCI function code") - configdata = Param.PciConfigData(Super, "PCI Config data") - configspace = Param.PciConfigAll(Super, "PCI Configspace") + configdata = Param.PciConfigData(parent.any, "PCI Config data") + configspace = Param.PciConfigAll(parent.any, "PCI Configspace") diff --git a/python/m5/objects/PhysicalMemory.mpy b/python/m5/objects/PhysicalMemory.mpy index d1e4ad4b4..e6df2a161 100644 --- a/python/m5/objects/PhysicalMemory.mpy +++ b/python/m5/objects/PhysicalMemory.mpy @@ -4,4 +4,4 @@ simobj PhysicalMemory(FunctionalMemory): type = 'PhysicalMemory' range = Param.AddrRange("Device Address") file = Param.String('', "memory mapped file") - mmu = Param.MemoryController(Super, "Memory Controller") + mmu = Param.MemoryController(parent.any, "Memory Controller") diff --git a/python/m5/objects/Platform.mpy b/python/m5/objects/Platform.mpy index d0510eaf8..a71ab3b77 100644 --- a/python/m5/objects/Platform.mpy +++ b/python/m5/objects/Platform.mpy @@ -2,4 +2,4 @@ simobj Platform(SimObject): type = 'Platform' abstract = True interrupt_frequency = Param.Tick(1200, "frequency of interrupts") - intrctrl = Param.IntrControl(Super, "interrupt controller") + intrctrl = Param.IntrControl(parent.any, "interrupt controller") diff --git a/python/m5/objects/SimConsole.mpy b/python/m5/objects/SimConsole.mpy index fb74f1775..3588a949d 100644 --- a/python/m5/objects/SimConsole.mpy +++ b/python/m5/objects/SimConsole.mpy @@ -5,7 +5,7 @@ simobj ConsoleListener(SimObject): simobj SimConsole(SimObject): type = 'SimConsole' append_name = Param.Bool(True, "append name() to filename") - intr_control = Param.IntrControl(Super, "interrupt controller") + intr_control = Param.IntrControl(parent.any, "interrupt controller") listener = Param.ConsoleListener("console listener") number = Param.Int(0, "console number") output = Param.String('console', "file to dump output to") diff --git a/python/m5/objects/SimpleDisk.mpy b/python/m5/objects/SimpleDisk.mpy index c4dd5435b..b616fb3d1 100644 --- a/python/m5/objects/SimpleDisk.mpy +++ b/python/m5/objects/SimpleDisk.mpy @@ -1,4 +1,4 @@ simobj SimpleDisk(SimObject): type = 'SimpleDisk' disk = Param.DiskImage("Disk Image") - physmem = Param.PhysicalMemory(Super, "Physical Memory") + physmem = Param.PhysicalMemory(parent.any, "Physical Memory") diff --git a/python/m5/objects/Tsunami.mpy b/python/m5/objects/Tsunami.mpy index cfe23977e..a8471cee2 100644 --- a/python/m5/objects/Tsunami.mpy +++ b/python/m5/objects/Tsunami.mpy @@ -4,12 +4,12 @@ from Platform import Platform simobj Tsunami(Platform): type = 'Tsunami' pciconfig = Param.PciConfigAll("PCI configuration") - system = Param.BaseSystem(Super, "system") + system = Param.BaseSystem(parent.any, "system") interrupt_frequency = Param.Int(1024, "frequency of interrupts") simobj TsunamiCChip(FooPioDevice): type = 'TsunamiCChip' - tsunami = Param.Tsunami(Super, "Tsunami") + tsunami = Param.Tsunami(parent.any, "Tsunami") simobj TsunamiFake(FooPioDevice): type = 'TsunamiFake' @@ -18,8 +18,8 @@ simobj TsunamiIO(FooPioDevice): type = 'TsunamiIO' time = Param.UInt64(1136073600, "System time to use (0 for actual time, default is 1/1/06)") - tsunami = Param.Tsunami(Super, "Tsunami") + tsunami = Param.Tsunami(parent.any, "Tsunami") simobj TsunamiPChip(FooPioDevice): type = 'TsunamiPChip' - tsunami = Param.Tsunami(Super, "Tsunami") + tsunami = Param.Tsunami(parent.any, "Tsunami") diff --git a/python/m5/objects/Uart.mpy b/python/m5/objects/Uart.mpy index 76ee8805f..5a6c25f8e 100644 --- a/python/m5/objects/Uart.mpy +++ b/python/m5/objects/Uart.mpy @@ -2,5 +2,5 @@ from Device import PioDevice simobj Uart(PioDevice): type = 'Uart' - console = Param.SimConsole(Super, "The console") + console = Param.SimConsole(parent.any, "The console") size = Param.Addr(0x8, "Device size") diff --git a/python/m5/smartdict.py b/python/m5/smartdict.py index 4ea8210d3..1ba5d8410 100644 --- a/python/m5/smartdict.py +++ b/python/m5/smartdict.py @@ -74,6 +74,12 @@ class SmartDict(dict): return other / self.convert(other) + # __getitem__ uses dict.get() to return 'False' if the key is not + # found (rather than raising KeyError). Note that this does *not* + # set the key's value to 'False' in the dict, so that even after + # we call env['foo'] we still get a meaningful answer from "'foo' + # in env" (which calls dict.__contains__, which we do not + # override). def __getitem__(self, key): return self.Proxy(dict.get(self, key, 'False')) diff --git a/sim/sim_object.cc b/sim/sim_object.cc index 818648b98..559415102 100644 --- a/sim/sim_object.cc +++ b/sim/sim_object.cc @@ -61,14 +61,29 @@ namespace Stats { // // SimObject constructor: used to maintain static simObjectList // +SimObject::SimObject(Params *p) + : _params(p) +{ +#ifdef DEBUG + doDebugBreak = false; +#endif + + doRecordEvent = !Stats::event_ignore.match(name()); + simObjectList.push_back(this); +} + +// +// SimObject constructor: used to maintain static simObjectList +// SimObject::SimObject(const string &_name) - : objName(_name) + : _params(new Params) { + _params->name = _name; #ifdef DEBUG doDebugBreak = false; #endif - doRecordEvent = !Stats::event_ignore.match(_name); + doRecordEvent = !Stats::event_ignore.match(name()); simObjectList.push_back(this); } diff --git a/sim/sim_object.hh b/sim/sim_object.hh index b8a3090ad..db8d4f4d3 100644 --- a/sim/sim_object.hh +++ b/sim/sim_object.hh @@ -48,8 +48,16 @@ */ class SimObject : public Serializable, protected StartupCallback { + public: + struct Params { + std::string name; + }; + protected: - std::string objName; + Params *_params; + + public: + const Params *params() const { return _params; } private: friend class Serializer; @@ -60,15 +68,12 @@ class SimObject : public Serializable, protected StartupCallback static SimObjectList simObjectList; public: - -// for Params struct -#include "simobj/param/SimObject.hh" - + SimObject(Params *_params); SimObject(const std::string &_name); virtual ~SimObject() {} - virtual const std::string name() const { return objName; } + virtual const std::string name() const { return params()->name; } // initialization pass of all objects. // Gets invoked after construction, before unserialize. |