diff options
-rw-r--r-- | SConscript | 158 | ||||
-rw-r--r-- | arch/SConscript | 73 | ||||
-rw-r--r-- | arch/alpha/SConscript | 49 | ||||
-rw-r--r-- | arch/alpha/alpha_linux_process.cc | 27 | ||||
-rw-r--r-- | arch/alpha/ev5.cc | 10 | ||||
-rwxr-xr-x | arch/isa_parser.py | 60 | ||||
-rw-r--r-- | arch/mips/SConscript | 50 | ||||
-rw-r--r-- | arch/sparc/SConscript | 52 | ||||
-rw-r--r-- | build/SConstruct | 9 | ||||
-rw-r--r-- | cpu/SConscript | 99 | ||||
-rw-r--r-- | cpu/cpu_models.py | 71 | ||||
-rw-r--r-- | cpu/o3/cpu.cc | 3 | ||||
-rw-r--r-- | cpu/simple/cpu.cc | 17 | ||||
-rw-r--r-- | cpu/simple/cpu.hh | 1 | ||||
-rw-r--r-- | cpu/static_inst.hh | 6 | ||||
-rw-r--r-- | dev/alpha_access.h | 6 | ||||
-rw-r--r-- | dev/alpha_console.cc | 46 | ||||
-rw-r--r-- | dev/alpha_console.hh | 2 | ||||
-rw-r--r-- | sim/system.cc | 8 |
19 files changed, 479 insertions, 268 deletions
diff --git a/SConscript b/SConscript index 1b99566ea..966cb6d3e 100644 --- a/SConscript +++ b/SConscript @@ -86,31 +86,7 @@ base_sources = Split(''' cpu/exetrace.cc cpu/pc_event.cc cpu/static_inst.cc - cpu/o3/2bit_local_pred.cc - cpu/o3/alpha_dyn_inst.cc - cpu/o3/alpha_cpu.cc - cpu/o3/alpha_cpu_builder.cc - cpu/o3/bpred_unit.cc - cpu/o3/btb.cc - cpu/o3/commit.cc - cpu/o3/decode.cc - cpu/o3/fetch.cc - cpu/o3/free_list.cc - cpu/o3/cpu.cc - cpu/o3/iew.cc - cpu/o3/inst_queue.cc - cpu/o3/ldstq.cc - cpu/o3/mem_dep_unit.cc - cpu/o3/ras.cc - cpu/o3/rename.cc - cpu/o3/rename_map.cc - cpu/o3/rob.cc - cpu/o3/sat_counter.cc - cpu/o3/store_set.cc - cpu/o3/tournament_pred.cc - cpu/fast/cpu.cc cpu/sampler/sampler.cc - cpu/simple/cpu.cc cpu/trace/reader/mem_trace_reader.cc cpu/trace/reader/ibm_reader.cc cpu/trace/reader/itx_reader.cc @@ -118,41 +94,6 @@ base_sources = Split(''' cpu/trace/opt_cpu.cc cpu/trace/trace_cpu.cc - encumbered/cpu/full/bpred.cc - encumbered/cpu/full/commit.cc - encumbered/cpu/full/cpu.cc - encumbered/cpu/full/create_vector.cc - encumbered/cpu/full/cv_spec_state.cc - encumbered/cpu/full/dd_queue.cc - encumbered/cpu/full/dep_link.cc - encumbered/cpu/full/dispatch.cc - encumbered/cpu/full/dyn_inst.cc - encumbered/cpu/full/execute.cc - encumbered/cpu/full/fetch.cc - encumbered/cpu/full/floss_reasons.cc - encumbered/cpu/full/fu_pool.cc - encumbered/cpu/full/inst_fifo.cc - encumbered/cpu/full/instpipe.cc - encumbered/cpu/full/issue.cc - encumbered/cpu/full/ls_queue.cc - encumbered/cpu/full/machine_queue.cc - encumbered/cpu/full/pipetrace.cc - encumbered/cpu/full/readyq.cc - encumbered/cpu/full/reg_info.cc - encumbered/cpu/full/rob_station.cc - encumbered/cpu/full/spec_memory.cc - encumbered/cpu/full/spec_state.cc - encumbered/cpu/full/storebuffer.cc - encumbered/cpu/full/writeback.cc - encumbered/cpu/full/iq/iq_station.cc - encumbered/cpu/full/iq/iqueue.cc - encumbered/cpu/full/iq/segmented/chain_info.cc - encumbered/cpu/full/iq/segmented/chain_wire.cc - encumbered/cpu/full/iq/segmented/iq_seg.cc - encumbered/cpu/full/iq/segmented/iq_segmented.cc - encumbered/cpu/full/iq/segmented/seg_chain.cc - encumbered/cpu/full/iq/seznec/iq_seznec.cc - encumbered/cpu/full/iq/standard/iq_standard.cc encumbered/mem/functional/main.cc mem/base_hier.cc @@ -224,6 +165,45 @@ base_sources = Split(''' sim/trace_context.cc ''') +# Old FullCPU sources +full_cpu_sources = Split(''' + encumbered/cpu/full/bpred.cc + encumbered/cpu/full/commit.cc + encumbered/cpu/full/cpu.cc + encumbered/cpu/full/create_vector.cc + encumbered/cpu/full/cv_spec_state.cc + encumbered/cpu/full/dd_queue.cc + encumbered/cpu/full/dep_link.cc + encumbered/cpu/full/dispatch.cc + encumbered/cpu/full/dyn_inst.cc + encumbered/cpu/full/execute.cc + encumbered/cpu/full/fetch.cc + encumbered/cpu/full/floss_reasons.cc + encumbered/cpu/full/fu_pool.cc + encumbered/cpu/full/inst_fifo.cc + encumbered/cpu/full/instpipe.cc + encumbered/cpu/full/issue.cc + encumbered/cpu/full/ls_queue.cc + encumbered/cpu/full/machine_queue.cc + encumbered/cpu/full/pipetrace.cc + encumbered/cpu/full/readyq.cc + encumbered/cpu/full/reg_info.cc + encumbered/cpu/full/rob_station.cc + encumbered/cpu/full/spec_memory.cc + encumbered/cpu/full/spec_state.cc + encumbered/cpu/full/storebuffer.cc + encumbered/cpu/full/writeback.cc + encumbered/cpu/full/iq/iq_station.cc + encumbered/cpu/full/iq/iqueue.cc + encumbered/cpu/full/iq/segmented/chain_info.cc + encumbered/cpu/full/iq/segmented/chain_wire.cc + encumbered/cpu/full/iq/segmented/iq_seg.cc + encumbered/cpu/full/iq/segmented/iq_segmented.cc + encumbered/cpu/full/iq/segmented/seg_chain.cc + encumbered/cpu/full/iq/seznec/iq_seznec.cc + encumbered/cpu/full/iq/standard/iq_standard.cc + ''') + # MySql sources mysql_sources = Split(''' base/mysql.cc @@ -320,6 +300,11 @@ syscall_emulation_sources = Split(''' sim/syscall_emul.cc ''') +# The following stuff (targetarch code and global define of THE_ISA) +# are legacy things that assume we're only compiling one ISA at a +# time. These will have to go away if we want to build a binary that +# supports multiple ISAs. + targetarch_files = Split(''' alpha_linux_process.hh alpha_memory.hh @@ -338,18 +323,22 @@ for f in targetarch_files: env.Command('targetarch/' + f, 'arch/%s/%s' % (env['TARGET_ISA'], f), '''echo '#include "arch/%s/%s"' > $TARGET''' % (env['TARGET_ISA'], f)) -# Let the target architecture define what sources it needs -arch_source = SConscript('arch/%s/SConscript' % env['TARGET_ISA'], - build_dir = 'build/%s/' % env['BUILD_DIR'], - exports = 'env', duplicate = False) - # Add a flag defining what THE_ISA should be for all compilation env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) -SConscript('arch/SConscript', exports = 'env', duplicate = False) +arch_sources = SConscript('arch/SConscript', + exports = 'env', duplicate = False) + +cpu_sources = SConscript('cpu/SConscript', + exports = 'env', duplicate = False) + +# This is outside of cpu/SConscript since the source directory isn't +# underneath 'cpu'. +if 'FullCPU' in env['CPU_MODELS']: + cpu_sources += full_cpu_sources # Set up complete list of sources based on configuration. -sources = base_sources + arch_source +sources = base_sources + arch_sources + cpu_sources if env['FULL_SYSTEM']: sources += full_system_sources @@ -366,27 +355,6 @@ for opt in env.ExportOptions: ################################################### # -# Add an SCons scanner for ISA files -# -################################################### -import SCons.Scanner - -def ISAScan(): - return SCons.Scanner.Classic("ISAScan", - "$ISASUFFIXES", - "SRCDIR", - '^[ \t]*##[ \t]*include[ \t]*"([^>"]+)"') - -def ISAPath(env, dir, target=None, source=None, a=None): - return (Dir(env['SRCDIR']), Dir('.')) - -iscan = Scanner(function = ISAScan().scan, skeys = [".isa", ".ISA"], - path_function = ISAPath) -env.Append(SCANNERS = iscan) - - -################################################### -# # Special build rules. # ################################################### @@ -397,22 +365,6 @@ env.Command(Split('base/traceflags.hh base/traceflags.cc'), 'base/traceflags.py', 'python $SOURCE $TARGET.base') -# several files are generated from arch/$TARGET_ISA/isa_desc. -env.Command(Split(''' - arch/%(targetisa)s/decoder.cc - arch/%(targetisa)s/decoder.hh - arch/%(targetisa)s/alpha_o3_exec.cc - arch/%(targetisa)s/fast_cpu_exec.cc - arch/%(targetisa)s/simple_cpu_exec.cc - arch/%(targetisa)s/full_cpu_exec.cc''' % - {'targetisa': env['TARGET_ISA']}), - Split(''' - arch/%s/isa/main.isa - arch/isa_parser.py''' % - env['TARGET_ISA']), - '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/%s' % env['TARGET_ISA']) - - # libelf build is described in its own SConscript file. # SConscript-local is the per-config build, which just copies some # header files into a place where they can be found. diff --git a/arch/SConscript b/arch/SConscript index 2d8e34b7b..d237b0b1f 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -31,11 +31,17 @@ import os.path # Import build environment variable from SConstruct. Import('env') +# Right now there are no source files immediately in this directory +sources = [] + +################################################################# # # ISA "switch header" generation. # # Auto-generate arch headers that include the right ISA-specific # header based on the setting of THE_ISA preprocessor variable. +# +################################################################# # List of headers to generate isa_switch_hdrs = Split(''' @@ -72,3 +78,70 @@ switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string, # Instantiate actions for each header for hdr in isa_switch_hdrs: env.Command(hdr, [], switch_hdr_action) + +################################################################# +# +# Include architecture-specific files. +# +################################################################# + +# +# Build a SCons scanner for ISA files +# +import SCons.Scanner + +def ISAScan(): + return SCons.Scanner.Classic("ISAScan", + "$ISASUFFIXES", + "SRCDIR", + '^[ \t]*##[ \t]*include[ \t]*"([^>"]+)"') + +def ISAPath(env, dir, target=None, source=None, a=None): + return (Dir(env['SRCDIR']), Dir('.')) + +iscan = Scanner(function = ISAScan().scan, skeys = [".isa", ".ISA"], + path_function = ISAPath) +env.Append(SCANNERS = iscan) + +# +# Now create a Builder object that uses isa_parser.py to generate C++ +# output from the ISA description (*.isa) files. +# + +# Convert to File node to fix path +isa_parser = File('isa_parser.py') +cpu_models_file = File('#m5/cpu/cpu_models.py') + +# This sucks in the defintions of the CpuModel objects. +execfile(cpu_models_file.srcnode().abspath) + +# Several files are generated from the ISA description. +# We always get the basic decoder and header file. +isa_desc_gen_files = Split('decoder.cc decoder.hh') +# We also get an execute file for each selected CPU model. +isa_desc_gen_files += [CpuModel.dict[cpu].filename + for cpu in env['CPU_MODELS']] + +# The emitter patches up the sources & targets to include the +# autogenerated files as targets and isa parser itself as a source. +def isa_desc_emitter(target, source, env): + return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source) + +# Pieces are in place, so create the builder. +isa_desc_builder = Builder(action='$SOURCES $TARGET.dir $CPU_MODELS', + source_scanner = iscan, + emitter = isa_desc_emitter) + +env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder }) + +# +# Now include other ISA-specific sources from the ISA subdirectories. +# + +isa = env['TARGET_ISA'] # someday this may be a list of ISAs + +# Let the target architecture define what additional sources it needs +sources += SConscript(os.path.join(isa, 'SConscript'), + exports = 'env', duplicate = False) + +Return('sources') diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index a5ae77dac..050dfb9cf 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -43,40 +43,45 @@ Import('env') ################################################### # Base sources used by all configurations. -arch_base_sources = Split(''' - arch/alpha/decoder.cc - arch/alpha/alpha_o3_exec.cc - arch/alpha/fast_cpu_exec.cc - arch/alpha/simple_cpu_exec.cc - arch/alpha/full_cpu_exec.cc - arch/alpha/faults.cc - arch/alpha/isa_traits.cc +base_sources = Split(''' + faults.cc + isa_traits.cc ''') # Full-system sources -arch_full_system_sources = Split(''' - arch/alpha/alpha_memory.cc - arch/alpha/arguments.cc - arch/alpha/ev5.cc - arch/alpha/osfpal.cc - arch/alpha/stacktrace.cc - arch/alpha/vtophys.cc +full_system_sources = Split(''' + alpha_memory.cc + arguments.cc + ev5.cc + osfpal.cc + stacktrace.cc + vtophys.cc ''') # Syscall emulation (non-full-system) sources -arch_syscall_emulation_sources = Split(''' - arch/alpha/alpha_common_syscall_emul.cc - arch/alpha/alpha_linux_process.cc - arch/alpha/alpha_tru64_process.cc +syscall_emulation_sources = Split(''' + alpha_common_syscall_emul.cc + alpha_linux_process.cc + alpha_tru64_process.cc ''') # Set up complete list of sources based on configuration. -sources = arch_base_sources +sources = base_sources if env['FULL_SYSTEM']: - sources += arch_full_system_sources + sources += full_system_sources else: - sources += arch_syscall_emulation_sources + sources += syscall_emulation_sources + +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +# Add in files generated by the ISA description. +isa_desc_files = env.ISADesc('isa/main.isa') +# Only non-header files need to be compiled. +isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')] +sources += isa_desc_sources Return('sources') diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 783b189cc..16ebcca7b 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -41,6 +41,31 @@ using namespace std; using namespace AlphaISA; +/// Target pipe() handler. Even though this is a generic Posix call, +/// the Alpha return convention is funky, so that makes it +/// Alpha-specific. +SyscallReturn +pipeFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + int fds[2], sim_fds[2]; + int pipe_retval = pipe(fds); + + if (pipe_retval < 0) { + // error + return pipe_retval; + } + + sim_fds[0] = process->alloc_fd(fds[0]); + sim_fds[1] = process->alloc_fd(fds[1]); + + // Alpha Linux convention for pipe() is that fd[0] is returned as + // the return value of the function, and fd[1] is returned in r20. + xc->regs.intRegFile[20] = sim_fds[1]; + return sim_fds[0]; +} + + /// Target uname() handler. static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, Process *process, @@ -159,7 +184,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 39 */ SyscallDesc("setpgid", unimplementedFunc), /* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc), /* 41 */ SyscallDesc("dup", unimplementedFunc), - /* 42 */ SyscallDesc("pipe", unimplementedFunc), + /* 42 */ SyscallDesc("pipe", pipeFunc), /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc), /* 44 */ SyscallDesc("osf_profil", unimplementedFunc), /* 45 */ SyscallDesc("open", openFunc<Linux>), diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 3f1c17adc..34b328a39 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -70,12 +70,15 @@ AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow) // Machine dependent functions // void -AlphaISA::initCPU(RegFile *regs) +AlphaISA::initCPU(RegFile *regs, int cpuId) { - initIPRs(regs); + initIPRs(regs, cpuId); // CPU comes up with PAL regs enabled swap_palshadow(regs, true); + regs->intRegFile[16] = cpuId; + regs->intRegFile[0] = cpuId; + regs->pc = regs->ipr[IPR_PAL_BASE] + (new ResetFault)->vect(); regs->npc = regs->pc + sizeof(MachInst); } @@ -106,13 +109,14 @@ const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { // // void -AlphaISA::initIPRs(RegFile *regs) +AlphaISA::initIPRs(RegFile *regs, int cpuId) { uint64_t *ipr = regs->ipr; bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); ipr[IPR_PAL_BASE] = PalBase; ipr[IPR_MCSR] = 0x6; + ipr[IPR_PALtemp16] = cpuId; } diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 0d18f4d89..6508ca02a 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -712,44 +712,6 @@ yacc.yacc() # ##################################################################### -################ -# CpuModel class -# -# The CpuModel class encapsulates everything we need to know about a -# particular CPU model. - -class CpuModel: - # List of all CPU models. Accessible as CpuModel.list. - list = [] - - # Constructor. Automatically adds models to CpuModel.list. - def __init__(self, name, filename, includes, strings): - self.name = name - self.filename = filename # filename for output exec code - self.includes = includes # include files needed in exec file - # The 'strings' dict holds all the per-CPU symbols we can - # substitute into templates etc. - self.strings = strings - # Add self to list. - CpuModel.list.append(self) - -# Define CPU models. The following lines should contain the only -# CPU-model-specific information in this file. Note that the ISA -# description itself should have *no* CPU-model-specific content. -CpuModel('SimpleCPU', 'simple_cpu_exec.cc', - '#include "cpu/simple/cpu.hh"', - { 'CPU_exec_context': 'SimpleCPU' }) -CpuModel('FastCPU', 'fast_cpu_exec.cc', - '#include "cpu/fast/cpu.hh"', - { 'CPU_exec_context': 'FastCPU' }) -CpuModel('FullCPU', 'full_cpu_exec.cc', - '#include "encumbered/cpu/full/dyn_inst.hh"', - { 'CPU_exec_context': 'DynInst' }) - -CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc', - '#include "cpu/o3/alpha_dyn_inst.hh"', - { 'CPU_exec_context': 'AlphaDynInst<AlphaSimpleImpl>' }) - # Expand template with CPU-specific references into a dictionary with # an entry for each CPU model name. The entry key is the model name # and the corresponding value is the template with the CPU-specific @@ -758,7 +720,7 @@ def expand_cpu_symbols_to_dict(template): # Protect '%'s that don't go with CPU-specific terms t = re.sub(r'%(?!\(CPU_)', '%%', template) result = {} - for cpu in CpuModel.list: + for cpu in cpu_models: result[cpu.name] = t % cpu.strings return result @@ -817,7 +779,7 @@ class GenCode: # concatenates all the individual strings in the operands. def __add__(self, other): exec_output = {} - for cpu in CpuModel.list: + for cpu in cpu_models: n = cpu.name exec_output[n] = self.exec_output[n] + other.exec_output[n] return GenCode(self.header_output + other.header_output, @@ -831,7 +793,7 @@ class GenCode: self.header_output = pre + self.header_output self.decoder_output = pre + self.decoder_output self.decode_block = pre + self.decode_block - for cpu in CpuModel.list: + for cpu in cpu_models: self.exec_output[cpu.name] = pre + self.exec_output[cpu.name] # Wrap the decode block in a pair of strings (e.g., 'case foo:' @@ -1752,7 +1714,7 @@ def preprocess_isa_desc(isa_desc): # # Read in and parse the ISA description. # -def parse_isa_desc(isa_desc_file, output_dir, include_path): +def parse_isa_desc(isa_desc_file, output_dir): # set a global var for the input filename... used in error messages global input_filename input_filename = isa_desc_file @@ -1782,7 +1744,7 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): update_if_needed(output_dir + '/decoder.hh', file_template % vars()) # generate decoder.cc - includes = '#include "%s/decoder.hh"' % include_path + includes = '#include "decoder.hh"' global_output = global_code.decoder_output namespace_output = namespace_code.decoder_output # namespace_output += namespace_code.decode_block @@ -1790,8 +1752,8 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): update_if_needed(output_dir + '/decoder.cc', file_template % vars()) # generate per-cpu exec files - for cpu in CpuModel.list: - includes = '#include "%s/decoder.hh"\n' % include_path + for cpu in cpu_models: + includes = '#include "decoder.hh"\n' includes += cpu.includes global_output = global_code.exec_output[cpu.name] namespace_output = namespace_code.exec_output[cpu.name] @@ -1799,6 +1761,12 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): update_if_needed(output_dir + '/' + cpu.filename, file_template % vars()) +# global list of CpuModel objects (see cpu_models.py) +cpu_models = [] + # Called as script: get args from command line. +# Args are: <path to cpu_models.py> <isa desc file> <output dir> <cpu models> if __name__ == '__main__': - parse_isa_desc(sys.argv[1], sys.argv[2], sys.argv[3]) + execfile(sys.argv[1]) # read in CpuModel definitions + cpu_models = [CpuModel.dict[cpu] for cpu in sys.argv[4:]] + parse_isa_desc(sys.argv[2], sys.argv[3]) diff --git a/arch/mips/SConscript b/arch/mips/SConscript index a6af91669..b8efa7ef9 100644 --- a/arch/mips/SConscript +++ b/arch/mips/SConscript @@ -40,42 +40,44 @@ Import('env') ################################################### # Base sources used by all configurations. -arch_base_sources = Split(''' - arch/mips/decoder.cc - arch/mips/mips_o3_exec.cc - arch/mips/fast_cpu_exec.cc - arch/mips/simple_cpu_exec.cc - arch/mips/full_cpu_exec.cc - arch/mips/faults.cc - arch/mips/isa_traits.cc +base_sources = Split(''' + faults.cc + isa_traits.cc ''') # Full-system sources -arch_full_system_sources = Split(''' - arch/mips/memory.cc - arch/mips/arguments.cc - arch/mips/mips34k.cc - arch/mips/osfpal.cc - arch/mips/stacktrace.cc - arch/mips/vtophys.cc +full_system_sources = Split(''' + memory.cc + arguments.cc + mips34k.cc + osfpal.cc + stacktrace.cc + vtophys.cc ''') # Syscall emulation (non-full-system) sources -arch_syscall_emulation_sources = Split(''' - arch/mips/common_syscall_emul.cc - arch/mips/linux_process.cc - arch/mips/tru64_process.cc +syscall_emulation_sources = Split(''' + common_syscall_emul.cc + linux_process.cc + tru64_process.cc ''') # Set up complete list of sources based on configuration. -sources = arch_base_sources +sources = base_sources if env['FULL_SYSTEM']: - sources += arch_full_system_sources + sources += full_system_sources else: - sources += arch_syscall_emulation_sources + sources += syscall_emulation_sources -for opt in env.ExportOptions: - env.ConfigFile(opt) +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +# Add in files generated by the ISA description. +isa_desc_files = env.ISADesc('isa/main.isa') +# Only non-header files need to be compiled. +isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')] +sources += isa_desc_sources Return('sources') diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript index d8a3749a1..fea31fd5d 100644 --- a/arch/sparc/SConscript +++ b/arch/sparc/SConscript @@ -40,43 +40,43 @@ Import('env') ################################################### # Base sources used by all configurations. -arch_base_sources = Split(''' - arch/sparc/decoder.cc - arch/sparc/alpha_o3_exec.cc - arch/sparc/fast_cpu_exec.cc - arch/sparc/simple_cpu_exec.cc - arch/sparc/full_cpu_exec.cc - arch/sparc/faults.cc - arch/sparc/isa_traits.cc +base_sources = Split(''' + faults.cc + isa_traits.cc ''') # Full-system sources -arch_full_system_sources = Split(''' - arch/sparc/alpha_memory.cc - arch/sparc/arguments.cc - arch/sparc/ev5.cc - arch/sparc/osfpal.cc - arch/sparc/stacktrace.cc - arch/sparc/vtophys.cc +full_system_sources = Split(''' + alpha_memory.cc + arguments.cc + ev5.cc + osfpal.cc + stacktrace.cc + vtophys.cc ''') # Syscall emulation (non-full-system) sources -arch_syscall_emulation_sources = Split(''' - arch/sparc/alpha_common_syscall_emul.cc - arch/sparc/alpha_linux_process.cc - arch/sparc/alpha_tru64_process.cc +syscall_emulation_sources = Split(''' + alpha_common_syscall_emul.cc + alpha_linux_process.cc + alpha_tru64_process.cc ''') -sources = arch_base_sources +sources = base_sources if env['FULL_SYSTEM']: - sources += arch_full_system_sources - if env['ALPHA_TLASER']: - sources += arch_turbolaser_sources + sources += full_system_sources else: - sources += arch_syscall_emulation_sources + sources += syscall_emulation_sources -for opt in env.ExportOptions: - env.ConfigFile(opt) +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +# Add in files generated by the ISA description. +isa_desc_files = env.ISADesc('isa/main.isa') +# Only non-header files need to be compiled. +isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')] +sources += isa_desc_sources Return('sources') diff --git a/build/SConstruct b/build/SConstruct index 38d404846..2d64afb3e 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -221,6 +221,9 @@ env = conf.Finish() # Define the universe of supported ISAs env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips'] +# Define the universe of supported CPU models +env['ALL_CPU_LIST'] = ['SimpleCPU', 'FastCPU', 'FullCPU', 'AlphaFullCPU'] + # Sticky options get saved in the options file so they persist from # one invocation to the next (unless overridden, in which case the new # value becomes sticky). @@ -251,6 +254,12 @@ sticky_opts.AddOptions( # Non-sticky options only apply to the current build. nonsticky_opts = Options(args=ARGUMENTS) nonsticky_opts.AddOptions( + # This really should be a sticky option, but there's a bug in + # scons 0.96.1 that causes ListOptions not to be able to be + # restored from a saved option file. It looks like this is fixed + # in 0.96.9, but there's a different bug in that version that means we + # can't just upgrade. + ListOption('CPU_MODELS', 'CPU models', 'all', env['ALL_CPU_LIST']), BoolOption('update_ref', 'Update test reference outputs', False) ) diff --git a/cpu/SConscript b/cpu/SConscript new file mode 100644 index 000000000..dbe174660 --- /dev/null +++ b/cpu/SConscript @@ -0,0 +1,99 @@ +# -*- mode:python -*- + +# Copyright (c) 2006 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import os.path + +# Import build environment variable from SConstruct. +Import('env') + +models_db = File('cpu_models.py') +execfile(models_db.srcnode().abspath) + +exec_sig_template = ''' +virtual Fault execute(%s *xc, Trace::InstRecord *traceData) const = 0; +''' + +def gen_cpu_exec_signatures(target, source, env): + f = open(str(target[0]), 'w') + print >> f, ''' +#ifndef __CPU_STATIC_INST_EXEC_SIGS_HH__ +#define __CPU_STATIC_INST_EXEC_SIGS_HH__ +''' + for cpu in env['CPU_MODELS']: + xc_type = CpuModel.dict[cpu].strings['CPU_exec_context'] + print >> f, exec_sig_template % xc_type + print >> f, ''' +#endif // __CPU_STATIC_INST_EXEC_SIGS_HH__ +''' + +env.Command('static_inst_exec_sigs.hh', models_db, gen_cpu_exec_signatures) + +sources = [] + +if 'SimpleCPU' in env['CPU_MODELS']: + sources += Split('simple/cpu.cc') + +if 'FastCPU' in env['CPU_MODELS']: + sources += Split('fast/cpu.cc') + +if 'AlphaFullCPU' in env['CPU_MODELS']: + sources += Split(''' + o3/2bit_local_pred.cc + o3/alpha_dyn_inst.cc + o3/alpha_cpu.cc + o3/alpha_cpu_builder.cc + o3/bpred_unit.cc + o3/btb.cc + o3/commit.cc + o3/decode.cc + o3/fetch.cc + o3/free_list.cc + o3/cpu.cc + o3/iew.cc + o3/inst_queue.cc + o3/ldstq.cc + o3/mem_dep_unit.cc + o3/ras.cc + o3/rename.cc + o3/rename_map.cc + o3/rob.cc + o3/sat_counter.cc + o3/store_set.cc + o3/tournament_pred.cc + ''') + +# FullCPU sources are included from m5/SConscript since they're not +# below this point in the file hierarchy. + +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +Return('sources') + diff --git a/cpu/cpu_models.py b/cpu/cpu_models.py new file mode 100644 index 000000000..675204e5b --- /dev/null +++ b/cpu/cpu_models.py @@ -0,0 +1,71 @@ +# Copyright (c) 2003-2006 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +################ +# CpuModel class +# +# The CpuModel class encapsulates everything the ISA parser needs to +# know about a particular CPU model. + +class CpuModel: + # Dict of available CPU model objects. Accessible as CpuModel.dict. + dict = {} + + # Constructor. Automatically adds models to CpuModel.dict. + def __init__(self, name, filename, includes, strings): + self.name = name + self.filename = filename # filename for output exec code + self.includes = includes # include files needed in exec file + # The 'strings' dict holds all the per-CPU symbols we can + # substitute into templates etc. + self.strings = strings + # Add self to dict + CpuModel.dict[name] = self + + +# +# Define CPU models. +# +# Parameters are: +# - name of model +# - filename for generated ISA execution file +# - includes needed for generated ISA execution file +# - substitution strings for ISA description templates +# + +CpuModel('SimpleCPU', 'simple_cpu_exec.cc', + '#include "cpu/simple/cpu.hh"', + { 'CPU_exec_context': 'SimpleCPU' }) +CpuModel('FastCPU', 'fast_cpu_exec.cc', + '#include "cpu/fast/cpu.hh"', + { 'CPU_exec_context': 'FastCPU' }) +CpuModel('FullCPU', 'full_cpu_exec.cc', + '#include "encumbered/cpu/full/dyn_inst.hh"', + { 'CPU_exec_context': 'DynInst' }) +CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc', + '#include "cpu/o3/alpha_dyn_inst.hh"', + { 'CPU_exec_context': 'AlphaDynInst<AlphaSimpleImpl>' }) + diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc index ffa157fbb..706657887 100644 --- a/cpu/o3/cpu.cc +++ b/cpu/o3/cpu.cc @@ -137,8 +137,6 @@ FullO3CPU<Impl>::FullO3CPU(Params ¶ms) system->execContexts[i] = new ExecContext(this, i, system, itb, dtb, mem); - // initialize CPU, including PC - TheISA::initCPU(&system->execContexts[i]->regs); execContexts.push_back(system->execContexts[i]); #else if (i < params.workload.size()) { @@ -250,6 +248,7 @@ FullO3CPU<Impl>::init() // that it can start properly. #if FULL_SYSTEM ExecContext *src_xc = system->execContexts[0]; + TheISA::initCPU(&src_xc->regs, src_xc->cpu_id); #else ExecContext *src_xc = thread[0]; #endif diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index d6f2ffd9f..a0a37f45a 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -84,6 +84,21 @@ SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w) { } + +void +SimpleCPU::init() +{ + BaseCPU::init(); +#if FULL_SYSTEM + for (int i = 0; i < execContexts.size(); ++i) { + ExecContext *xc = execContexts[i]; + + // initialize CPU, including PC + TheISA::initCPU(&xc->regs, xc->cpu_id); + } +#endif +} + void SimpleCPU::TickEvent::process() { @@ -124,8 +139,6 @@ SimpleCPU::SimpleCPU(Params *p) #if FULL_SYSTEM xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); - // initialize CPU, including PC - initCPU(&xc->regs); #else xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0); #endif // !FULL_SYSTEM diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index d3e0323b6..ed7b1e29b 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -68,6 +68,7 @@ class SimpleCPU : public BaseCPU public: // main simulation loop (one cycle) void tick(); + virtual void init(); private: struct TickEvent : public Event diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index db9e73714..5566f2f6d 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -316,7 +316,11 @@ class StaticInst : public StaticInstBase delete cachedDisassembly; } -#include "static_inst_impl.hh" +/** + * The execute() signatures are auto-generated by scons based on the + * set of CPU models we are compiling in today. + */ +#include "cpu/static_inst_exec_sigs.hh" /** * Return the target address for a PC-relative branch. diff --git a/dev/alpha_access.h b/dev/alpha_access.h index a20a05535..5a1df6f39 100644 --- a/dev/alpha_access.h +++ b/dev/alpha_access.h @@ -33,7 +33,7 @@ * System Console Memory Mapped Register Definition */ -#define ALPHA_ACCESS_VERSION (1303) +#define ALPHA_ACCESS_VERSION (1305) #ifdef CONSOLE typedef unsigned uint32_t; @@ -67,9 +67,7 @@ struct AlphaAccess uint64_t inputChar; // 68: Placeholder for input // MP boot - uint64_t bootStrapImpure; // 70: - uint32_t bootStrapCPU; // 78: - uint32_t align2; // 7C: Dummy placeholder for alignment + uint64_t cpuStack[64]; // 70: }; #endif // __ALPHA_ACCESS_H__ diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 87d8c4e93..85134b435 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -81,9 +81,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, alphaAccess->diskOperation = 0; alphaAccess->outputChar = 0; alphaAccess->inputChar = 0; - alphaAccess->bootStrapImpure = 0; - alphaAccess->bootStrapCPU = 0; - alphaAccess->align2 = 0; + bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); system->setAlphaAccess(addr); } @@ -123,9 +121,6 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data) case offsetof(AlphaAccess, numCPUs): *(uint32_t*)data = alphaAccess->numCPUs; break; - case offsetof(AlphaAccess, bootStrapCPU): - *(uint32_t*)data = alphaAccess->bootStrapCPU; - break; case offsetof(AlphaAccess, intrClockFrequency): *(uint32_t*)data = alphaAccess->intrClockFrequency; break; @@ -176,11 +171,14 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data) case offsetof(AlphaAccess, outputChar): *(uint64_t*)data = alphaAccess->outputChar; break; - case offsetof(AlphaAccess, bootStrapImpure): - *(uint64_t*)data = alphaAccess->bootStrapImpure; - break; default: - panic("Unknown 64bit access, %#x\n", daddr); + int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / + sizeof(alphaAccess->cpuStack[0]); + + if (cpunum >= 0 && cpunum < 64) + *(uint64_t*)data = alphaAccess->cpuStack[cpunum]; + else + panic("Unknown 64bit access, %#x\n", daddr); } break; default: @@ -240,24 +238,18 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) console->out((char)(val & 0xff)); break; - case offsetof(AlphaAccess, bootStrapImpure): - alphaAccess->bootStrapImpure = val; - break; - - case offsetof(AlphaAccess, bootStrapCPU): - warn("%d: Trying to launch another CPU!", curTick); - assert(val > 0 && "Must not access primary cpu"); - - other_xc = req->xc->system->execContexts[val]; - other_xc->regs.intRegFile[16] = val; - other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val; - other_xc->regs.intRegFile[0] = val; - other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure; other_xc->activate(); //Start the cpu break; default: - return new MachineCheckFault; + int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / + sizeof(alphaAccess->cpuStack[0]); + warn("%d: Trying to launch CPU number %d!", curTick, cpunum); + assert(val > 0 && "Must not access primary cpu"); + if (cpunum >= 0 && cpunum < 64) + alphaAccess->cpuStack[cpunum] = val; + else + panic("Unknown 64bit access, %#x\n", daddr); } return NoFault; @@ -288,8 +280,7 @@ AlphaConsole::Access::serialize(ostream &os) SERIALIZE_SCALAR(diskOperation); SERIALIZE_SCALAR(outputChar); SERIALIZE_SCALAR(inputChar); - SERIALIZE_SCALAR(bootStrapImpure); - SERIALIZE_SCALAR(bootStrapCPU); + SERIALIZE_ARRAY(cpuStack,64); } void @@ -311,8 +302,7 @@ AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(diskOperation); UNSERIALIZE_SCALAR(outputChar); UNSERIALIZE_SCALAR(inputChar); - UNSERIALIZE_SCALAR(bootStrapImpure); - UNSERIALIZE_SCALAR(bootStrapCPU); + UNSERIALIZE_ARRAY(cpuStack, 64); } void diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 74ad795f0..2d1c1e634 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -96,7 +96,7 @@ class AlphaConsole : public PioDevice BaseCPU *cpu; Addr addr; - static const Addr size = 0x80; // equal to sizeof(alpha_access); + static const Addr size = sizeof(struct AlphaAccess); public: /** Standard Constructor */ diff --git a/sim/system.cc b/sim/system.cc index ebeb5b244..41de8cee4 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -307,11 +307,9 @@ System::registerExecContext(ExecContext *xc, int id) void System::startup() { - if (!execContexts.empty()) { - // activate with zero delay so that we start ticking right - // away on cycle 0 - execContexts[0]->activate(0); - } + int i; + for (i = 0; i < execContexts.size(); i++) + execContexts[i]->activate(0); } void |