Re: [m5-dev] local APIC timer and bus frequency

2008-05-24 Thread Gabe Black
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

2008-05-24 Thread Gabe Black
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

2008-05-24 Thread Steve Reinhardt
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

2008-05-24 Thread Gabe Black
   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

2008-05-24 Thread nathan binkert
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
 ---