Enhancements to python config proxy class.

python/m5/config.py:
    - Enhanced Proxy class now supports subscripting, e.g.,
    parent.cpu[0] or even parent.cpu[0].icache.

    - Proxy also supports multiplication (e.g., parent.cycle * 3),
    though this feature has not been tested.

    - Subscript 0 works even on non-lists, so you can safely say
    cpu[0] and get the first cpu even if there's only one.

    - Changed name of proxy object from 'Super' to 'parent', and
    changed "wild card" notation from plain 'Super' to 'parent.any'.
python/m5/objects/AlphaConsole.mpy:
python/m5/objects/BaseCPU.mpy:
python/m5/objects/BaseSystem.mpy:
python/m5/objects/Device.mpy:
python/m5/objects/Ethernet.mpy:
python/m5/objects/Ide.mpy:
python/m5/objects/IntrControl.mpy:
python/m5/objects/Pci.mpy:
python/m5/objects/PhysicalMemory.mpy:
python/m5/objects/Platform.mpy:
python/m5/objects/SimConsole.mpy:
python/m5/objects/SimpleDisk.mpy:
python/m5/objects/Tsunami.mpy:
python/m5/objects/Uart.mpy:
    Change 'Super.foo' to 'parent.foo' (and 'Super' to 'parent.any').

--HG--
extra : convert_revision : f996d0a3366d5e3e60ae5973691148c3d7cd497d
This commit is contained in:
Steve Reinhardt 2005-03-16 00:40:48 -05:00
parent 42753edb3c
commit c8538d6a7e
15 changed files with 118 additions and 63 deletions

View file

@ -139,25 +139,90 @@ class Singleton(type):
##################################################################### #####################################################################
class Proxy(object): class Proxy(object):
def __init__(self, path = ()): def __init__(self, path):
self._object = None 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): 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): def __setattr__(self, attr, value):
if not attr.startswith('_'): if not attr.startswith('_'):
raise AttributeError, 'cannot set attribute %s' % attr raise AttributeError, 'cannot set attribute %s' % attr
super(Proxy, self).__setattr__(attr, value) super(Proxy, self).__setattr__(attr, value)
def _convert(self): # support indexing on proxies (e.g., parent.cpu[0])
obj = self._object def __getitem__(self, key):
for attr in self._path: if not isinstance(key, int):
obj = obj.__getattribute__(attr) raise TypeError, "Proxy object requires integer index"
return obj 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
Super = Proxy() # 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)
# global object for handling parent.foo proxies
parent = ProxyFactory()
def isSubClass(value, cls): def isSubClass(value, cls):
try: try:
@ -643,50 +708,40 @@ class Node(object):
if issubclass(child.realtype, realtype): if issubclass(child.realtype, realtype):
if obj is not None: if obj is not None:
raise AttributeError, \ raise AttributeError, \
'Super matched more than one: %s %s' % \ 'parent.any matched more than one: %s %s' % \
(obj.path, child.path) (obj.path, child.path)
obj = child obj = child
return obj, obj is not None return obj, obj is not None
try: try:
obj = self obj = self
for node in path[:-1]: for (node,index) in path[:-1]:
obj = obj.child_names[node] 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): if obj.child_names.has_key(last):
value = obj.child_names[last] value = obj.child_names[last]
if issubclass(value.realtype, realtype): return Proxy.getindex(value, index), True
return value, 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): elif obj.param_names.has_key(last):
value = obj.param_names[last] value = obj.param_names[last]
realtype._convert(value.value) realtype._convert(value.value)
return value.value, True return Proxy.getindex(value.value, index), True
except KeyError: except KeyError:
pass pass
return None, False return None, False
def unproxy(self, ptype, value): def unproxy(self, param, ptype):
if not isinstance(value, Proxy): if not isinstance(param, Proxy):
return value return param
return param.unproxy(self, ptype)
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 fixup(self): def fixup(self):
self.all[self.path] = self self.all[self.path] = self
@ -697,9 +752,9 @@ class Node(object):
try: try:
if isinstance(pval, (list, tuple)): 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: else:
param.value = self.unproxy(ptype, pval) param.value = self.unproxy(pval, ptype)
except: except:
print 'Error while fixing up %s:%s' % (self.path, param.name) print 'Error while fixing up %s:%s' % (self.path, param.name)
raise raise
@ -1337,7 +1392,7 @@ class SimObject(ConfigNode, ParamType):
# 'from config import *' is invoked. Try to keep this reasonably # 'from config import *' is invoked. Try to keep this reasonably
# short to avoid polluting other namespaces. # short to avoid polluting other namespaces.
__all__ = ['ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', __all__ = ['ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam',
'Super', 'Enum', 'parent', 'Enum',
'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16',
'Int32', 'UInt32', 'Int64', 'UInt64', 'Int32', 'UInt32', 'Int64', 'UInt64',
'Counter', 'Addr', 'Tick', 'Percent', 'Counter', 'Addr', 'Tick', 'Percent',

View file

@ -2,8 +2,8 @@ from Device import PioDevice
simobj AlphaConsole(PioDevice): simobj AlphaConsole(PioDevice):
type = 'AlphaConsole' type = 'AlphaConsole'
cpu = Param.BaseCPU(Super, "Processor") cpu = Param.BaseCPU(parent.any, "Processor")
disk = Param.SimpleDisk("Simple Disk") disk = Param.SimpleDisk("Simple Disk")
num_cpus = Param.Int(1, "Number of CPUs") num_cpus = Param.Int(1, "Number of CPUs")
sim_console = Param.SimConsole(Super, "The Simulator Console") sim_console = Param.SimConsole(parent.any, "The Simulator Console")
system = Param.BaseSystem(Super, "system object") system = Param.BaseSystem(parent.any, "system object")

View file

@ -8,7 +8,7 @@ simobj BaseCPU(SimObject):
dtb = Param.AlphaDTB("Data TLB") dtb = Param.AlphaDTB("Data TLB")
itb = Param.AlphaITB("Instruction TLB") itb = Param.AlphaITB("Instruction TLB")
mem = Param.FunctionalMemory("memory") mem = Param.FunctionalMemory("memory")
system = Param.BaseSystem(Super, "system object") system = Param.BaseSystem(parent.any, "system object")
else: else:
workload = VectorParam.Process("processes to run") workload = VectorParam.Process("processes to run")

View file

@ -1,8 +1,8 @@
simobj BaseSystem(SimObject): simobj BaseSystem(SimObject):
type = 'BaseSystem' type = 'BaseSystem'
abstract = True abstract = True
memctrl = Param.MemoryController(Super, "memory controller") memctrl = Param.MemoryController(parent.any, "memory controller")
physmem = Param.PhysicalMemory(Super, "phsyical memory") physmem = Param.PhysicalMemory(parent.any, "phsyical memory")
kernel = Param.String("file that contains the kernel code") kernel = Param.String("file that contains the kernel code")
console = Param.String("file that contains the console code") console = Param.String("file that contains the console code")
pal = Param.String("file that contains palcode") pal = Param.String("file that contains palcode")

View file

@ -14,7 +14,7 @@ simobj FooPioDevice(FunctionalMemory):
type = 'PioDevice' type = 'PioDevice'
abstract = True abstract = True
addr = Param.Addr("Device Address") 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") io_bus = Param.Bus(NULL, "The IO Bus to attach to")
pio_latency = Param.Tick(1, "Programmed IO latency in bus cycles") pio_latency = Param.Tick(1, "Programmed IO latency in bus cycles")
@ -25,7 +25,7 @@ simobj FooDmaDevice(FooPioDevice):
simobj PioDevice(FooPioDevice): simobj PioDevice(FooPioDevice):
type = 'PioDevice' type = 'PioDevice'
abstract = True abstract = True
platform = Param.Platform(Super, "Platform") platform = Param.Platform(parent.any, "Platform")
simobj DmaDevice(PioDevice): simobj DmaDevice(PioDevice):
type = 'DmaDevice' type = 'DmaDevice'

View file

@ -49,8 +49,8 @@ simobj EtherDev(DmaDevice):
intr_delay = Param.Tick(0, "Interrupt Delay in microseconds") intr_delay = Param.Tick(0, "Interrupt Delay in microseconds")
payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload") 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")
tlaser = Param.Turbolaser(Super, "Turbolaser") tlaser = Param.Turbolaser(parent.any, "Turbolaser")
simobj NSGigE(PciDevice): simobj NSGigE(PciDevice):
type = 'NSGigE' type = 'NSGigE'
@ -73,7 +73,7 @@ simobj NSGigE(PciDevice):
intr_delay = Param.Tick(0, "Interrupt Delay in microseconds") intr_delay = Param.Tick(0, "Interrupt Delay in microseconds")
payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload") 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): simobj EtherDevInt(EtherInt):
type = 'EtherDevInt' type = 'EtherDevInt'

View file

@ -7,7 +7,7 @@ simobj IdeDisk(SimObject):
delay = Param.Tick(1, "Fixed disk delay in microseconds") delay = Param.Tick(1, "Fixed disk delay in microseconds")
driveID = Param.IdeID('master', "Drive ID") driveID = Param.IdeID('master', "Drive ID")
image = Param.DiskImage("Disk image") image = Param.DiskImage("Disk image")
physmem = Param.PhysicalMemory(Super, "Physical memory") physmem = Param.PhysicalMemory(parent.any, "Physical memory")
simobj IdeController(PciDevice): simobj IdeController(PciDevice):
type = 'IdeController' type = 'IdeController'

View file

@ -1,3 +1,3 @@
simobj IntrControl(SimObject): simobj IntrControl(SimObject):
type = 'IntrControl' type = 'IntrControl'
cpu = Param.BaseCPU(Super, "the cpu") cpu = Param.BaseCPU(parent.any, "the cpu")

View file

@ -47,5 +47,5 @@ simobj PciDevice(DmaDevice):
pci_bus = Param.Int("PCI bus") pci_bus = Param.Int("PCI bus")
pci_dev = Param.Int("PCI device number") pci_dev = Param.Int("PCI device number")
pci_func = Param.Int("PCI function code") pci_func = Param.Int("PCI function code")
configdata = Param.PciConfigData(Super, "PCI Config data") configdata = Param.PciConfigData(parent.any, "PCI Config data")
configspace = Param.PciConfigAll(Super, "PCI Configspace") configspace = Param.PciConfigAll(parent.any, "PCI Configspace")

View file

@ -4,4 +4,4 @@ simobj PhysicalMemory(FunctionalMemory):
type = 'PhysicalMemory' type = 'PhysicalMemory'
range = Param.AddrRange("Device Address") range = Param.AddrRange("Device Address")
file = Param.String('', "memory mapped file") file = Param.String('', "memory mapped file")
mmu = Param.MemoryController(Super, "Memory Controller") mmu = Param.MemoryController(parent.any, "Memory Controller")

View file

@ -2,4 +2,4 @@ simobj Platform(SimObject):
type = 'Platform' type = 'Platform'
abstract = True abstract = True
interrupt_frequency = Param.Tick(1200, "frequency of interrupts") interrupt_frequency = Param.Tick(1200, "frequency of interrupts")
intrctrl = Param.IntrControl(Super, "interrupt controller") intrctrl = Param.IntrControl(parent.any, "interrupt controller")

View file

@ -5,7 +5,7 @@ simobj ConsoleListener(SimObject):
simobj SimConsole(SimObject): simobj SimConsole(SimObject):
type = 'SimConsole' type = 'SimConsole'
append_name = Param.Bool(True, "append name() to filename") 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") listener = Param.ConsoleListener("console listener")
number = Param.Int(0, "console number") number = Param.Int(0, "console number")
output = Param.String('console', "file to dump output to") output = Param.String('console', "file to dump output to")

View file

@ -1,4 +1,4 @@
simobj SimpleDisk(SimObject): simobj SimpleDisk(SimObject):
type = 'SimpleDisk' type = 'SimpleDisk'
disk = Param.DiskImage("Disk Image") disk = Param.DiskImage("Disk Image")
physmem = Param.PhysicalMemory(Super, "Physical Memory") physmem = Param.PhysicalMemory(parent.any, "Physical Memory")

View file

@ -4,12 +4,12 @@ from Platform import Platform
simobj Tsunami(Platform): simobj Tsunami(Platform):
type = 'Tsunami' type = 'Tsunami'
pciconfig = Param.PciConfigAll("PCI configuration") pciconfig = Param.PciConfigAll("PCI configuration")
system = Param.BaseSystem(Super, "system") system = Param.BaseSystem(parent.any, "system")
interrupt_frequency = Param.Int(1024, "frequency of interrupts") interrupt_frequency = Param.Int(1024, "frequency of interrupts")
simobj TsunamiCChip(FooPioDevice): simobj TsunamiCChip(FooPioDevice):
type = 'TsunamiCChip' type = 'TsunamiCChip'
tsunami = Param.Tsunami(Super, "Tsunami") tsunami = Param.Tsunami(parent.any, "Tsunami")
simobj TsunamiFake(FooPioDevice): simobj TsunamiFake(FooPioDevice):
type = 'TsunamiFake' type = 'TsunamiFake'
@ -18,8 +18,8 @@ simobj TsunamiIO(FooPioDevice):
type = 'TsunamiIO' type = 'TsunamiIO'
time = Param.UInt64(1136073600, time = Param.UInt64(1136073600,
"System time to use (0 for actual time, default is 1/1/06)") "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): simobj TsunamiPChip(FooPioDevice):
type = 'TsunamiPChip' type = 'TsunamiPChip'
tsunami = Param.Tsunami(Super, "Tsunami") tsunami = Param.Tsunami(parent.any, "Tsunami")

View file

@ -2,5 +2,5 @@ from Device import PioDevice
simobj Uart(PioDevice): simobj Uart(PioDevice):
type = 'Uart' type = 'Uart'
console = Param.SimConsole(Super, "The console") console = Param.SimConsole(parent.any, "The console")
size = Param.Addr(0x8, "Device size") size = Param.Addr(0x8, "Device size")