From c13ea339dccf54261f753424ff9eb516d97b34a1 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 23 Feb 2006 08:16:59 -0500 Subject: [PATCH 1/6] Add pipe() syscall to Alpha Linux emulation. arch/alpha/alpha_linux_process.cc: Add pipeFunc. --HG-- extra : convert_revision : c094d2dff993d5e60bc43b7cd4b9586c15c634a3 --- arch/alpha/alpha_linux_process.cc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 783b189ccd..16ebcca7be 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), From 9949ccf16158668ad0d9282a97c372a69de09532 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 23 Feb 2006 13:27:23 -0500 Subject: [PATCH 2/6] Cast enum to int to fix compile error from regression. --HG-- extra : convert_revision : 2d998ec7393e1c08c7552f7e586160d579eab2b1 From 99484cfae81f3f01ccdfcd273ddc2bdb41e6456b Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 23 Feb 2006 14:31:15 -0500 Subject: [PATCH 3/6] Create a Builder object for .isa files in arch/SConscript. Start using SCons File objects to avoid fixed paths in subordinate SConscripts. SConscript: Push isa_parser stuff (including .isa scanner) down into arch/SConscript. arch/SConscript: Create a Builder object for .isa files, including existing scanner. Return file objects generated by isa-specific SConscript back up to parent. arch/alpha/SConscript: arch/mips/SConscript: arch/sparc/SConscript: Convert sources to scons File objects, so file names can be specified relative to the current directory. Invoke new builder for isa description, and get generated sources from there (instead of listing them explicitly). arch/isa_parser.py: Get rid of third argument ("include_path"). It was a pain to generate this from scons, and it turned out it's not needed anyway, since the only included file (decoder.hh) will be in the same directory as the sources. --HG-- extra : convert_revision : 36861bcef36763f229704d8cb7a642b4486a3581 --- SConscript | 57 +++++----------------------------- arch/SConscript | 72 +++++++++++++++++++++++++++++++++++++++++++ arch/alpha/SConscript | 49 ++++++++++++++++------------- arch/isa_parser.py | 8 ++--- arch/mips/SConscript | 50 +++++++++++++++--------------- arch/sparc/SConscript | 52 +++++++++++++++---------------- 6 files changed, 163 insertions(+), 125 deletions(-) diff --git a/SConscript b/SConscript index 49f06af7d5..3e607caa41 100644 --- a/SConscript +++ b/SConscript @@ -320,6 +320,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 +343,14 @@ 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) # Set up complete list of sources based on configuration. -sources = base_sources + arch_source +sources = base_sources + arch_sources if env['FULL_SYSTEM']: sources += full_system_sources @@ -364,27 +365,6 @@ if env['USE_MYSQL']: for opt in env.ExportOptions: env.ConfigFile(opt) -################################################### -# -# 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,27 +377,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/%s/decoder.cc - arch/%s/decoder.hh - arch/%s/alpha_o3_exec.cc - arch/%s/fast_cpu_exec.cc - arch/%s/simple_cpu_exec.cc - arch/%s/full_cpu_exec.cc''' % - (env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'], - 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 2d8e34b7b2..51f6cc0231 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,69 @@ 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. +# + +# several files are generated from the ISA description +isa_desc_gen_files = Split(''' + decoder.cc + alpha_o3_exec.cc + fast_cpu_exec.cc + simple_cpu_exec.cc + full_cpu_exec.cc + decoder.hh + ''') + +# Convert to File node to fix path +isa_parser = File('isa_parser.py') + +# 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] + source) + +# Pieces are in place, so create the builder. +isa_desc_builder = Builder(action='${SOURCES[0]} ${SOURCES[1]} $TARGET.dir', + 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 a5ae77dac7..050dfb9cf1 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/isa_parser.py b/arch/isa_parser.py index b92d267c9e..a2bf31a0c9 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1751,7 +1751,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 @@ -1781,7 +1781,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,7 +1790,7 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): # generate per-cpu exec files for cpu in CpuModel.list: - includes = '#include "%s/decoder.hh"\n' % include_path + includes = '#include "decoder.hh"\n' includes += cpu.includes global_output = global_code.exec_output[cpu.name] namespace_output = namespace_code.exec_output[cpu.name] @@ -1800,4 +1800,4 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): # Called as script: get args from command line. if __name__ == '__main__': - parse_isa_desc(sys.argv[1], sys.argv[2], sys.argv[3]) + parse_isa_desc(sys.argv[1], sys.argv[2]) diff --git a/arch/mips/SConscript b/arch/mips/SConscript index a6af916698..b8efa7ef98 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 d8a3749a14..fea31fd5d2 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') From 1166d4f0bfe67a9dc178be3454b4f0eac38663ad Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 23 Feb 2006 14:50:16 -0500 Subject: [PATCH 4/6] Get rid of the xc from the alphaAccess/alphaConsole backdoor device. Now allocate an array of stacks indexed by cpu number which specify cpu stacks and are initialized by cpu 0. Othe cpus spin waiting for their stacks before continuing. This change *REQUIRES* a the new console code to operate correctly. arch/alpha/ev5.cc: Add cpuId to initCPU/initIPR functions cpu/o3/cpu.cc: cpu/simple/cpu.cc: cpu/simple/cpu.hh: Move the cpu initilization into an init() function since it now needs the CPU id which isn't known at construction dev/alpha_access.h: dev/alpha_console.cc: dev/alpha_console.hh: instead of the bootstrap variables, add space for 64 cpu stacks in the alpha access structure. sim/system.cc: start all cpus immediately rather than just the first one --HG-- extra : convert_revision : 28c218af49d885a0f203ada419f16f25d5a3f37b --- arch/alpha/ev5.cc | 10 +++++++--- cpu/o3/cpu.cc | 3 +-- cpu/simple/cpu.cc | 17 ++++++++++++++-- cpu/simple/cpu.hh | 1 + dev/alpha_access.h | 6 ++---- dev/alpha_console.cc | 46 +++++++++++++++++--------------------------- dev/alpha_console.hh | 2 +- sim/system.cc | 8 +++----- 8 files changed, 48 insertions(+), 45 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 125affd031..bd076dae4a 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] + fault_addr[Reset_Fault]; regs->npc = regs->pc + sizeof(MachInst); } @@ -116,13 +119,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/cpu/o3/cpu.cc b/cpu/o3/cpu.cc index adc7b6bbc2..6ea0ed7c7b 100644 --- a/cpu/o3/cpu.cc +++ b/cpu/o3/cpu.cc @@ -137,8 +137,6 @@ FullO3CPU::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::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 70217f0bb1..2438e49f63 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 - TheISA::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 0f72512374..5647495920 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -66,6 +66,7 @@ class SimpleCPU : public BaseCPU public: // main simulation loop (one cycle) void tick(); + virtual void init(); private: struct TickEvent : public Event diff --git a/dev/alpha_access.h b/dev/alpha_access.h index a20a055353..5a1df6f393 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 61b4446285..a520e7ea97 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -80,9 +80,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); } @@ -122,9 +120,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; @@ -175,11 +170,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: @@ -239,24 +237,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 Machine_Check_Fault; + 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 No_Fault; @@ -287,8 +279,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 @@ -310,8 +301,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 74ad795f09..2d1c1e634e 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 990145826b..bf639b4083 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -306,11 +306,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 From 4f831bc5610abfdb94ddfed9af5f1398182ff0b4 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 23 Feb 2006 15:08:08 -0500 Subject: [PATCH 5/6] ev5.cc: SCCS merged arch/alpha/ev5.cc: SCCS merged --HG-- extra : convert_revision : 9d70c1d461dab0ec016fd0616d74a49942aac659 --- arch/alpha/ev5.cc | 70 ++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index bd076dae4a..14b87b16fa 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -79,7 +79,7 @@ AlphaISA::initCPU(RegFile *regs, int cpuId) regs->intRegFile[16] = cpuId; regs->intRegFile[0] = cpuId; - regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault]; + regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr(ResetFault); regs->npc = regs->pc + sizeof(MachInst); } @@ -87,25 +87,15 @@ AlphaISA::initCPU(RegFile *regs, int cpuId) // // alpha exceptions - value equals trap address, update with MD_FAULT_TYPE // -Addr -AlphaISA::fault_addr[Num_Faults] = { - 0x0000, /* No_Fault */ - 0x0001, /* Reset_Fault */ - 0x0401, /* Machine_Check_Fault */ - 0x0501, /* Arithmetic_Fault */ - 0x0101, /* Interrupt_Fault */ - 0x0201, /* Ndtb_Miss_Fault */ - 0x0281, /* Pdtb_Miss_Fault */ - 0x0301, /* Alignment_Fault */ - 0x0381, /* DTB_Fault_Fault */ - 0x0381, /* DTB_Acv_Fault */ - 0x0181, /* ITB_Miss_Fault */ - 0x0181, /* ITB_Fault_Fault */ - 0x0081, /* ITB_Acv_Fault */ - 0x0481, /* Unimplemented_Opcode_Fault */ - 0x0581, /* Fen_Fault */ - 0x2001, /* Pal_Fault */ - 0x0501, /* Integer_Overflow_Fault: maps to Arithmetic_Fault */ +const Addr +AlphaISA::fault_addr(Fault fault) +{ + //Check for the system wide faults + if(fault == NoFault) return 0x0000; + else if(fault == MachineCheckFault) return 0x0401; + else if(fault == AlignmentFault) return 0x0301; + //Deal with the alpha specific faults + return ((AlphaFault*)fault)->vect; }; const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { @@ -172,7 +162,7 @@ AlphaISA::processInterrupts(CPU *cpu) if (ipl && ipl > ipr[IPR_IPLR]) { ipr[IPR_ISR] = summary; ipr[IPR_INTID] = ipl; - cpu->trap(Interrupt_Fault); + cpu->trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", ipr[IPR_IPLR], ipl, summary); } @@ -193,23 +183,23 @@ AlphaISA::zeroRegisters(CPU *cpu) void ExecContext::ev5_trap(Fault fault) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", FaultName(fault), regs.pc); - cpu->recordEvent(csprintf("Fault %s", FaultName(fault))); + DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc); + cpu->recordEvent(csprintf("Fault %s", fault->name)); assert(!misspeculating()); kernelStats->fault(fault); - if (fault == Arithmetic_Fault) + if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); AlphaISA::InternalProcReg *ipr = regs.ipr; // exception restart address - if (fault != Interrupt_Fault || !inPalMode()) + if (fault != InterruptFault || !inPalMode()) ipr[AlphaISA::IPR_EXC_ADDR] = regs.pc; - if (fault == Pal_Fault || fault == Arithmetic_Fault /* || - fault == Interrupt_Fault && !inPalMode() */) { + if (fault == PalFault || fault == ArithmeticFault /* || + fault == InterruptFault && !inPalMode() */) { // traps... skip faulting instruction ipr[AlphaISA::IPR_EXC_ADDR] += 4; } @@ -217,7 +207,7 @@ ExecContext::ev5_trap(Fault fault) if (!inPalMode()) AlphaISA::swap_palshadow(®s, true); - regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; + regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr(fault); regs.npc = regs.pc + sizeof(MachInst); } @@ -226,13 +216,13 @@ void AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) { InternalProcReg *ipr = regs->ipr; - bool use_pc = (fault == No_Fault); + bool use_pc = (fault == NoFault); - if (fault == Arithmetic_Fault) + if (fault == ArithmeticFault) panic("arithmetic faults NYI..."); // compute exception restart address - if (use_pc || fault == Pal_Fault || fault == Arithmetic_Fault) { + if (use_pc || fault == PalFault || fault == ArithmeticFault) { // traps... skip faulting instruction ipr[IPR_EXC_ADDR] = regs->pc + 4; } else { @@ -242,7 +232,7 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) // jump to expection address (PAL PC bit set here as well...) if (!use_pc) - regs->npc = ipr[IPR_PAL_BASE] + fault_addr[fault]; + regs->npc = ipr[IPR_PAL_BASE] + fault_addr(fault); else regs->npc = ipr[IPR_PAL_BASE] + pc; @@ -255,7 +245,7 @@ ExecContext::hwrei() uint64_t *ipr = regs.ipr; if (!inPalMode()) - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); @@ -269,7 +259,7 @@ ExecContext::hwrei() } // FIXME: XXX check for interrupts? XXX - return No_Fault; + return NoFault; } uint64_t @@ -367,12 +357,12 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_DTB_IAP: case AlphaISA::IPR_ITB_IA: case AlphaISA::IPR_ITB_IAP: - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; default: // invalid IPR - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; } @@ -391,7 +381,7 @@ ExecContext::setIpr(int idx, uint64_t val) uint64_t old; if (misspeculating()) - return No_Fault; + return NoFault; switch (idx) { case AlphaISA::IPR_PALtemp0: @@ -537,7 +527,7 @@ ExecContext::setIpr(int idx, uint64_t val) case AlphaISA::IPR_ITB_PTE_TEMP: case AlphaISA::IPR_DTB_PTE_TEMP: // read-only registers - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; case AlphaISA::IPR_HWINT_CLR: case AlphaISA::IPR_SL_XMIT: @@ -639,11 +629,11 @@ ExecContext::setIpr(int idx, uint64_t val) default: // invalid IPR - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } // no error... - return No_Fault; + return NoFault; } /** From 51647e7bec8e8607fc5713b4ace2c24ce8a7455a Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 23 Feb 2006 17:00:29 -0500 Subject: [PATCH 6/6] Enable building only selected CPU models via new scons CPU_MODELS parameter. For example: scons CPU_MODELS="SimpleCPU,FullCPU" ALPHA_SE/m5.debug Unfortunately the option is not sticky due to a scons bug with saving & restoring ListOption parameters. SConscript: Separate out cpu-model-specific files so they can be conditionally included based on value of new CPU_MODELS parameter. Most of these are now handled in cpu/SConscript, except for FullCPU which is still in this file. arch/SConscript: The set of CPU-model-specific execute files must now be determined from the CPU_MODELS parameter, via the new cpu_models.py file. Also pass the list of configured CPU models to isa_parser.py. arch/isa_parser.py: Move CpuModel definition and objects out to a separate file so they can be shared with scons. Global list of CPU models to generate code for is now controlled by command-line parameters (so we can do only a subset of the available ones). build/SConstruct: Define new CPU_MODELS ListOption. cpu/static_inst.hh: Rename static_inst_impl.hh to static_inst_exec_sigs.hh. --HG-- extra : convert_revision : 163df32a76d4c05900490b2bce4c7962a5e3f614 --- SConscript | 108 ++++++++++++++++++++------------------------- arch/SConscript | 25 ++++++----- arch/isa_parser.py | 53 +++++----------------- build/SConstruct | 9 ++++ cpu/SConscript | 99 +++++++++++++++++++++++++++++++++++++++++ cpu/cpu_models.py | 71 +++++++++++++++++++++++++++++ cpu/static_inst.hh | 6 ++- 7 files changed, 256 insertions(+), 115 deletions(-) create mode 100644 cpu/SConscript create mode 100644 cpu/cpu_models.py diff --git a/SConscript b/SConscript index 3e607caa41..966cb6d3e8 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 @@ -349,8 +329,16 @@ env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) 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_sources +sources = base_sources + arch_sources + cpu_sources if env['FULL_SYSTEM']: sources += full_system_sources diff --git a/arch/SConscript b/arch/SConscript index 51f6cc0231..d237b0b1f6 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -108,26 +108,27 @@ env.Append(SCANNERS = iscan) # output from the ISA description (*.isa) files. # -# several files are generated from the ISA description -isa_desc_gen_files = Split(''' - decoder.cc - alpha_o3_exec.cc - fast_cpu_exec.cc - simple_cpu_exec.cc - full_cpu_exec.cc - decoder.hh - ''') - # 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] + source) + 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[0]} ${SOURCES[1]} $TARGET.dir', +isa_desc_builder = Builder(action='$SOURCES $TARGET.dir $CPU_MODELS', source_scanner = iscan, emitter = isa_desc_emitter) diff --git a/arch/isa_parser.py b/arch/isa_parser.py index a2bf31a0c9..6508ca02aa 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -712,43 +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' }) - # 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 @@ -757,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 @@ -816,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, @@ -830,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:' @@ -1789,7 +1752,7 @@ def parse_isa_desc(isa_desc_file, output_dir): update_if_needed(output_dir + '/decoder.cc', file_template % vars()) # generate per-cpu exec files - for cpu in CpuModel.list: + for cpu in cpu_models: includes = '#include "decoder.hh"\n' includes += cpu.includes global_output = global_code.exec_output[cpu.name] @@ -1798,6 +1761,12 @@ def parse_isa_desc(isa_desc_file, output_dir): 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: if __name__ == '__main__': - parse_isa_desc(sys.argv[1], sys.argv[2]) + 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/build/SConstruct b/build/SConstruct index 38d4048466..2d64afb3ec 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 0000000000..dbe174660f --- /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 0000000000..675204e5ba --- /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' }) + diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 5106dcf06e..a0287a2de8 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -314,7 +314,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.