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
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
Re: [m5-dev] local APIC timer and bus frequency
Steve Reinhardt wrote: 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.) What do you mean by common indexing scheme? What I'm talking about doesn't allow for index aliasing or anything like that so I think I'm missing something. If you're talking about DepTags, I'd actually be happy to see those go. They've caused a number of very subtle and VERY annoying bugs to find and fix. I'm thinking it would be more like a two dimensional register space (file, index) rather than a two dimensional space projected into one which can lead to accidental overlaps. I can see how that might be more complicated though. 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. If it's a template parameter I think that does basically what you're saying. 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. There are two benefits I see. First off, you can keep track of things statically and update them only as necessary for things like register flattening and predecoding in x86 which I mentioned below. The state as in registers isn't in the ISA, but this residual configuration information is, stuff like the old register window code I had using bits of the index to look into a register paging like structure. Second, it makes it easy for the different pieces of an instance of an ISA to communicate. Right now, they need to use accessors in the thread context and casting to get what they need. That's why I'd have had to add an accessor for the Interrupts object if I wanted the miscregfile to be able to communicate with it. 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 migh
[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] 8254 PIT (timer device) programming
I imagine it's both, and implementation dependent if an interrupt occurs when the PIT timer expires, but it's been a long time. I imagine the datasheet for at 8254 timer would be a good place to start. Ali On May 24, 2008, at 5:40 AM, Gabe Black wrote: 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 ___ 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() >> + >> +pr