Re: [m5-dev] local APIC timer and bus frequency
For now, I'm going to make the miscregfile have the event and cause an interrupt when the timer goes off. This really sounds crappy to me, but I'd have to add new functions to get at the interrupt object like there are for the TLB. That wouldn't be hard, but I wanted to point out I'd be adding a new function all over the place in the CPU before I went and did it in case that doesn't sound like a great idea. I personally think there are too many functions in too many places in the CPU which is probably unavoidable, but I'd prefer not to add another one. Also, while I was deciding what to do about the local APIC, I tried to boil down what exactly an ISA is in M5, what it should and shouldn't be doing, and if that suggested anything we should be doing differently. That's basically what follows, so if you don't care go ahead and stop reading. Basically, the ISA is a set of policies and a collection of state which directs them. The policies are layered on top of and direct the mechanisms of the CPU. This is different from how I think the ISAs have been built up to this point which was as a collection of objects which implemented the ISAs policies and which were plugged into the CPU. Essentially, the difference is that there would be a base TLB class which would contain the behavior of all TLBs, they translate addresses, they have entries, the evict things, blah blah, and the ISA would describe the policies that happened under and what state, the entries and control registers, that guided it. The TLB would call into the ISA to make decisions rather than the ISA defining a TLB which would automatically make the right decisions. Another important distinction here is that the state which controls the policies of the ISA, most of the MiscRegs, are part of the ISA, but the other registers are not. The policy directing how those registers are used, namely how they're indexed, is, but the actual registers themselves are not. Also, the way they're currently indexed, as integer/floating point/misc, should really be setup and managed by the ISA and not the CPU. The CPU would probably want to know what type a register is so it can have it's own policies layered on top, like for instance separate pools of resources for ints and floats, but it shouldn't force the ISA to glob those together. Even that might be too much, because at least for X86 there are registers which can be both floating point and integer depending on the instruction that uses them. So really, the cpu should just expect some number of local storage banks. In x86, those could correspond to the general (ha) purpose registers, x87/mmx registers, xmm registers, and control register backing storage. The control register backing storage could be broken down farther into the CR control registers, debug registers, performance counter registers, the LAPIC control registers, the MSRs, etc, etc. Like now, the CPU would be responsible for providing the ISA the illusion that that was how things worked, but the o3, for example, could keep track of the actual storage however it liked. Then, the ISA defined control register file(s) really are just register file(s) which have their accesses intercepted and acted on in some way. They could conceptually live in the TLB, Interrupt object, whatever, with the CPU actually keeping track of the state, aka what a read would return. The objects the ISA controls would be able to keep their own local cached versions of the control state in whatever way was convenient, like for instance as a lookup table for register windows. The objects would need to be able to refresh and reread the underlying control state to update their caching data structures in cases where the underlying storage was updated directly, like what NoEffect does right now. This takes care of some odd circumstances where you can have trouble bootstrapping the control state in, for instance, SE mode. You have to make sure everything actually uses the control state you're righting, but it has to do that when not all of the state has actually been set. Really, all that needs to be refreshed is the control state which is part of the ISA, not of the objects in the CPU. In that way, you don't have to refresh the TLBs, blah blah. You only have to make the ISA configure itself based on the (to the CPU) generic array of values stored in some of the register files. There also would be objects with state and policy which are dynamically generated like faults and instructions. The faults are policy with maybe a little bubble of controlling state in them, and the instructions are policy (how to execute) strapped onto generic objects. So now, all the policies and state particular to the ISA have been localized into one place, an abstract concept called the ISA. That might as well be an object since it has methods and fields just like an object would. Now that the ISA is an object, which might as well be
Re: [m5-dev] local APIC timer and bus frequency
Oh, and one thing I forgot, registers can be like faults where they're little islands of the ISA. They know how to translate indexes, and they could use bitunions, which if it works (I don't remember if it does) could be inherited from (or inherit, with some modifications) to be able to pull out the bitfields easily while having methods and whatnot. I keep thinking about how to get the parser to figure out inputs and outputs better, but really I'm thinking that might be better done explicitly and then propagated using the formats. If the parser goes from treating the ISA description as input and instead has the same functionality but becomes a python library to go into x86.py (for instance) which I'd like to do someday as well, it could be based on python classes and inheritance. I think generally if you have a class of instructions like IntOps, you know there will be Ra and Rb as inputs and Rc as outputs all the time, and if not you did something wrong. Anyway, that's an entirely different discussion. Gabe Gabe Black wrote: For now, I'm going to make the miscregfile have the event and cause an interrupt when the timer goes off. This really sounds crappy to me, but I'd have to add new functions to get at the interrupt object like there are for the TLB. That wouldn't be hard, but I wanted to point out I'd be adding a new function all over the place in the CPU before I went and did it in case that doesn't sound like a great idea. I personally think there are too many functions in too many places in the CPU which is probably unavoidable, but I'd prefer not to add another one. Also, while I was deciding what to do about the local APIC, I tried to boil down what exactly an ISA is in M5, what it should and shouldn't be doing, and if that suggested anything we should be doing differently. That's basically what follows, so if you don't care go ahead and stop reading. Basically, the ISA is a set of policies and a collection of state which directs them. The policies are layered on top of and direct the mechanisms of the CPU. This is different from how I think the ISAs have been built up to this point which was as a collection of objects which implemented the ISAs policies and which were plugged into the CPU. Essentially, the difference is that there would be a base TLB class which would contain the behavior of all TLBs, they translate addresses, they have entries, the evict things, blah blah, and the ISA would describe the policies that happened under and what state, the entries and control registers, that guided it. The TLB would call into the ISA to make decisions rather than the ISA defining a TLB which would automatically make the right decisions. Another important distinction here is that the state which controls the policies of the ISA, most of the MiscRegs, are part of the ISA, but the other registers are not. The policy directing how those registers are used, namely how they're indexed, is, but the actual registers themselves are not. Also, the way they're currently indexed, as integer/floating point/misc, should really be setup and managed by the ISA and not the CPU. The CPU would probably want to know what type a register is so it can have it's own policies layered on top, like for instance separate pools of resources for ints and floats, but it shouldn't force the ISA to glob those together. Even that might be too much, because at least for X86 there are registers which can be both floating point and integer depending on the instruction that uses them. So really, the cpu should just expect some number of local storage banks. In x86, those could correspond to the general (ha) purpose registers, x87/mmx registers, xmm registers, and control register backing storage. The control register backing storage could be broken down farther into the CR control registers, debug registers, performance counter registers, the LAPIC control registers, the MSRs, etc, etc. Like now, the CPU would be responsible for providing the ISA the illusion that that was how things worked, but the o3, for example, could keep track of the actual storage however it liked. Then, the ISA defined control register file(s) really are just register file(s) which have their accesses intercepted and acted on in some way. They could conceptually live in the TLB, Interrupt object, whatever, with the CPU actually keeping track of the state, aka what a read would return. The objects the ISA controls would be able to keep their own local cached versions of the control state in whatever way was convenient, like for instance as a lookup table for register windows. The objects would need to be able to refresh and reread the underlying control state to update their caching data structures in cases where the underlying storage was updated directly, like what NoEffect does right now. This takes care of some odd circumstances where you can have trouble bootstrapping the control
Re: [m5-dev] local APIC timer and bus frequency
Thanks for the email... can't say I really follow all the nuances after a quick read, but I'm glad you're thinking about it. Just a few comments off the top of my head: The common indexing scheme across all register types is something we inherited from SimpleScalar. It's not ideal for actually indexing into register files, but the main benefit is that it gives a single flat namespace for tracking register dependencies, which simplifies things. (At least is simplified the old FullCPU model; I assume it helps in O3 as well.) While I think doing heterogeneous ISAs could be useful, I don't want to lose performance for it, esp. in the common homogeneous case. My thought was that we'd always keep the ISA as a static parameter, but then compile and link in multiple instantiations of the CPU model for each ISA we cared about. I also don't think the ISA itself should have any state... CPUs or other components can have ISA-specific state, and the ISA can certainly have a lot of constants associated with it, but there shouldn't be any dynamic state associated solely with the ISA. Thus I don't see where making it an object has any advantages over the status quo. Steve On Sat, May 24, 2008 at 12:01 AM, Gabe Black [EMAIL PROTECTED] wrote: For now, I'm going to make the miscregfile have the event and cause an interrupt when the timer goes off. This really sounds crappy to me, but I'd have to add new functions to get at the interrupt object like there are for the TLB. That wouldn't be hard, but I wanted to point out I'd be adding a new function all over the place in the CPU before I went and did it in case that doesn't sound like a great idea. I personally think there are too many functions in too many places in the CPU which is probably unavoidable, but I'd prefer not to add another one. Also, while I was deciding what to do about the local APIC, I tried to boil down what exactly an ISA is in M5, what it should and shouldn't be doing, and if that suggested anything we should be doing differently. That's basically what follows, so if you don't care go ahead and stop reading. Basically, the ISA is a set of policies and a collection of state which directs them. The policies are layered on top of and direct the mechanisms of the CPU. This is different from how I think the ISAs have been built up to this point which was as a collection of objects which implemented the ISAs policies and which were plugged into the CPU. Essentially, the difference is that there would be a base TLB class which would contain the behavior of all TLBs, they translate addresses, they have entries, the evict things, blah blah, and the ISA would describe the policies that happened under and what state, the entries and control registers, that guided it. The TLB would call into the ISA to make decisions rather than the ISA defining a TLB which would automatically make the right decisions. Another important distinction here is that the state which controls the policies of the ISA, most of the MiscRegs, are part of the ISA, but the other registers are not. The policy directing how those registers are used, namely how they're indexed, is, but the actual registers themselves are not. Also, the way they're currently indexed, as integer/floating point/misc, should really be setup and managed by the ISA and not the CPU. The CPU would probably want to know what type a register is so it can have it's own policies layered on top, like for instance separate pools of resources for ints and floats, but it shouldn't force the ISA to glob those together. Even that might be too much, because at least for X86 there are registers which can be both floating point and integer depending on the instruction that uses them. So really, the cpu should just expect some number of local storage banks. In x86, those could correspond to the general (ha) purpose registers, x87/mmx registers, xmm registers, and control register backing storage. The control register backing storage could be broken down farther into the CR control registers, debug registers, performance counter registers, the LAPIC control registers, the MSRs, etc, etc. Like now, the CPU would be responsible for providing the ISA the illusion that that was how things worked, but the o3, for example, could keep track of the actual storage however it liked. Then, the ISA defined control register file(s) really are just register file(s) which have their accesses intercepted and acted on in some way. They could conceptually live in the TLB, Interrupt object, whatever, with the CPU actually keeping track of the state, aka what a read would return. The objects the ISA controls would be able to keep their own local cached versions of the control state in whatever way was convenient, like for instance as a lookup table for register windows. The objects would need to be able to refresh and reread the underlying control state to update their caching data
[m5-dev] 8254 PIT (timer device) programming
I'm at a point now where the kernel is trying to wait for the 8254 timer to tick 300 times before moving to the local APIC timer to use for timer interrupts. As we determined before, the 8254 is the same as the PIT used in Alpha Tsunami, so I'm going to move the Alpha code to a neutral location and use it in x86 as well. What is the event that the timer schedules? Is that a tick to update the counter, or is that to fire the periodic interrupt? If it's the former that seems really inefficient. If it's the later, then I'm a little concerned that the way the timer is being programmed by the OS isn't a factor in when it fires. That would especially be a problem with the tickless kernel where the timer interrupt doesn't happen all the time. I would imagine that has to happen by programming the timer not to go off for a while until it actually needs to. Gabe ___ m5-dev mailing list m5-dev@m5sim.org http://m5sim.org/mailman/listinfo/m5-dev
Re: [m5-dev] [PATCH] HG: Add compiled hg revision and date to the standard M5 output
I just got back from my trip. I'll try to review this in the next couple of days, but I'm going to work on getting the copyright stuff done first. Nate On Thu, May 22, 2008 at 2:01 PM, Ali Saidi [EMAIL PROTECTED] wrote: So this fixes some bugs in the previous version (specifically hginfo.cc being dependent on all variants of all objects and it seems to work with Nate's compile script). Any problems or should I commit it? Ali On May 22, 2008, at 5:02 PM, Ali Saidi wrote: # HG changeset patch # User Ali Saidi [EMAIL PROTECTED] # Date 1211490125 14400 # Node ID b9683f2d6b0cb9288bc5f107b193ee617310fce8 # Parent fc6b6643b9c611ee5367a3db99b0705e74d9b06d HG: Add compiled hg revision and date to the standard M5 output. diff --git a/src/SConscript b/src/SConscript --- a/src/SConscript +++ b/src/SConscript @@ -333,6 +333,15 @@ env.Command('base/traceflags.cc', flags, env.Command('base/traceflags.cc', flags, generate.traceFlagsCC) Source('base/traceflags.cc') +# Generate hginfo.cc +# Anything we pass as a source gets setup as a dependence so rather than +# passing the SConscript/hg dir/etc we just squirrel away the SConstruct +# directory in the environment and retrieve it later. This seems to +# be the only reliable way to get the information if we're building in +# a directory outside of the m5 directory +env['SConstructDir'] = str(SCons.Node.FS.default_fs.SConstruct_dir) +env.Command('base/hginfo.cc', None, generate.hgInfo) + # Build the zip file py_compiled = [] py_zip_depends = [] @@ -365,11 +374,20 @@ envList = [] # date.cc. def make_objs(sources, env): objs = [env.Object(s) for s in sources] + # make date.cc depend on all other objects so it always gets # recompiled whenever anything else does date_obj = env.Object('base/date.cc') + +# Abuse the SCons dependence code to make the generation +# of hginfo.cc dependend on all the other cc files and the +# compiling of hginfo.cc dependent on all the objects +# but hginfo.o +hg_obj = env.Object('base/hginfo.cc') +env.Depends('base/hginfo.cc', sources) env.Depends(date_obj, objs) -objs.append(date_obj) +env.Depends(hg_obj, objs) +objs.extend([date_obj,hg_obj]) return objs # Function to create a new build environment as clone of current diff --git a/src/python/generate.py b/src/python/generate.py --- a/src/python/generate.py +++ b/src/python/generate.py @@ -32,8 +32,7 @@ import sys import sys import zipfile -from os.path import basename -from os.path import exists +from os.path import basename, exists, isdir, join class DictImporter(object): '''This importer takes a dictionary of arbitrary module names that @@ -528,3 +527,39 @@ extern const Flags *compoundFlags[]; ''' f.close() + +def hgInfo(self, target, source, env): +try: +# The SConscript squirrels away the SConstructDir variable in the +# env for us. We can't pass it as a source parameter because that +# would setup a depedence between everything in the directory and +# above and this file. + +scons_dir = env['SConstructDir'] +import mercurial.hg, mercurial.ui, mercurial.util, mercurial.node +if not exists(scons_dir) or not isdir(scons_dir) or \ + not exists(join(scons_dir, .hg)): +raise ValueError +repo = mercurial.hg.repository(mercurial.ui.ui(), scons_dir) +rev = mercurial.node.nullrev + repo.changelog.count() +changenode = repo.changelog.node(rev) +changes = repo.changelog.read(changenode) +date = mercurial.util.datestr(changes[2]) + +hg_stats = file(str(target[0]), 'w') +print hg_stats, 'const char *hgRev = %s:%s;' % (rev, mercurial.node.hex(changenode)) +print hg_stats, 'const char *hgDate = %s;' % date +hg_stats.close() +mercurial.demandimport.disable() +except ImportError: +pass +except: +hg_stats = file(str(target[0]), 'w') +print hg_stats, 'const char *hgRev = Unknown;' +print hg_stats, 'const char *hgDate = Unknown;' +hg_stats.close() +mercurial.demandimport.disable() + + + + diff --git a/src/python/m5/main.py b/src/python/m5/main.py --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -269,6 +269,10 @@ def main(): print M5 compiled %s % internal.core.cvar.compileDate; print M5 started %s % datetime.datetime.now().ctime() print M5 executing on %s % socket.gethostname() + +print M5 revision %s % internal.core.cvar.hgRev +print M5 commit date %s % internal.core.cvar.hgDate + print command line:, for argv in sys.argv: print argv, diff --git a/src/python/swig/core.i b/src/python/swig/core.i ---