[gem5-dev] Re: gem5 Staging Branch created
Thanks, Bobby! And thanks to everyone who worked extra hard last week! We're planning on posting a retrospective after this release to try to improve our practices for next time. Expect to see that in the coming weeks. Have a great weekend! Cheers, Jason On Sat, May 2, 2020 at 10:23 AM Bobby Bruce via gem5-dev wrote: > Dear all, > > As of 10AM PST the gem5 Staging Branch (release-staging-v20.0.0.0) has been > created from the gem5 develop branch. Over the next two weeks we shall be > running rigorous tests on this branch to ensure the upcoming release is as > stable and bug-free as possible. We will then merge the release branch into > the master and develop branches, thus officially releasing gem5. > > In line with our contribution guidelines ( > > https://gem5.googlesource.com/public/gem5/+/refs/heads/develop/CONTRIBUTING.md > ), > we permit alterations to be submitted to this staging branch though these > should strictly be "last-minute" bug fixes, stability improvements, and > small alterations that will not affect the functionality of the codebase > (documentation/README improvements, etc.). All other changes should > continue to be submitted to the gem5 develop branch. > > We would like to thank everyone for the contributions made over the past > few months. This release would not be possible without your efforts. > > Kind regards, > Bobby > -- > Dr. Bobby R. Bruce > Room 2235, > Kemper Hall, UC Davis > Davis, > CA, 95616 > > web: https://www.bobbybruce.net > > Dr. Bobby R. Bruce > Room 2235, > Kemper Hall, UC Davis > Davis, > CA, 95616 > > web: https://www.bobbybruce.net > ___ > gem5-dev mailing list -- gem5-dev@gem5.org > To unsubscribe send an email to gem5-dev-le...@gem5.org > %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s > ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] gem5 Staging Branch created
Dear all, As of 10AM PST the gem5 Staging Branch (release-staging-v20.0.0.0) has been created from the gem5 develop branch. Over the next two weeks we shall be running rigorous tests on this branch to ensure the upcoming release is as stable and bug-free as possible. We will then merge the release branch into the master and develop branches, thus officially releasing gem5. In line with our contribution guidelines ( https://gem5.googlesource.com/public/gem5/+/refs/heads/develop/CONTRIBUTING.md), we permit alterations to be submitted to this staging branch though these should strictly be "last-minute" bug fixes, stability improvements, and small alterations that will not affect the functionality of the codebase (documentation/README improvements, etc.). All other changes should continue to be submitted to the gem5 develop branch. We would like to thank everyone for the contributions made over the past few months. This release would not be possible without your efforts. Kind regards, Bobby -- Dr. Bobby R. Bruce Room 2235, Kemper Hall, UC Davis Davis, CA, 95616 web: https://www.bobbybruce.net Dr. Bobby R. Bruce Room 2235, Kemper Hall, UC Davis Davis, CA, 95616 web: https://www.bobbybruce.net ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: MESI_Three_level prefetcher page crossing
Pouya Fotouhi has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/28048 ) Change subject: mem-ruby: MESI_Three_level prefetcher page crossing .. mem-ruby: MESI_Three_level prefetcher page crossing This patch allows MESI_Three_level using the Ruby prefetcher to safely cross page boundaries by determining if an address is bad and cannot be mapped to a memory controller. Change-Id: I675a13dfa6deb5b6a9f986ced5a3130436db911d Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28048 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- M configs/ruby/MESI_Three_Level.py M src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm 2 files changed, 16 insertions(+), 2 deletions(-) Approvals: Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/configs/ruby/MESI_Three_Level.py b/configs/ruby/MESI_Three_Level.py index 0e9ef09..61d6c52 100644 --- a/configs/ruby/MESI_Three_Level.py +++ b/configs/ruby/MESI_Three_Level.py @@ -127,7 +127,7 @@ nonunit_filter = 256, train_misses = 5, num_startup_pfs = 4, -cross_page = False +cross_page = True ) l0_cntrl = L0Cache_Controller( diff --git a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm index da89bf5..3639ef2 100644 --- a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm +++ b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm @@ -140,6 +140,7 @@ PF_Load, desc="Load request from prefetcher"; PF_Ifetch, desc="Instruction fetch request from prefetcher"; PF_Store,desc="Exclusive load request from prefetcher"; +PF_Bad_Addr, desc="Throw away prefetch request due to bad address generation"; } // TYPES @@ -323,7 +324,16 @@ in_port(optionalQueue_in, RubyRequest, prefetchQueue, desc="...", rank = 2) { if (optionalQueue_in.isReady(clockEdge())) { peek(optionalQueue_in, RubyRequest) { -if (in_msg.Type == RubyRequestType:IFETCH) { +// first check for valid address +MachineID mid := mapAddressToMachine(in_msg.LineAddress, MachineType:Directory); +NodeID nid := machineIDToNodeID(mid); +int nidint := IDToInt(nid); +int numDirs := machineCount(MachineType:Directory); +if (nidint >= numDirs) { + Entry cache_entry := static_cast(Entry, "pointer", Dcache.getNullEntry()); + TBE tbe := TBEs.getNullEntry(); + trigger(Event:PF_Bad_Addr, in_msg.LineAddress, cache_entry, tbe); +} else if (in_msg.Type == RubyRequestType:IFETCH) { // Instruction Prefetch Entry icache_entry := getICacheEntry(in_msg.LineAddress); if (is_valid(icache_entry)) { @@ -1164,4 +1174,8 @@ o_popIncomingResponseQueue; kd_wakeUpDependents; } + + transition(I, PF_Bad_Addr) { +pq_popPrefetchQueue; + } } -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/28048 To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I675a13dfa6deb5b6a9f986ced5a3130436db911d Gerrit-Change-Number: 28048 Gerrit-PatchSet: 3 Gerrit-Owner: Giacomo Travaglini Gerrit-Reviewer: Ciro Santilli Gerrit-Reviewer: Jason Lowe-Power Gerrit-Reviewer: Pouya Fotouhi Gerrit-Reviewer: Timothy Hayes Gerrit-Reviewer: kokoro Gerrit-MessageType: merged ___ gem5-dev mailing list -- gem5-dev@gem5.org To unsubscribe send an email to gem5-dev-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: MESI_Three_level prefetcher support
Pouya Fotouhi has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/27715 ) Change subject: mem-ruby: MESI_Three_level prefetcher support .. mem-ruby: MESI_Three_level prefetcher support Add support for the Ruby stride prefetcher to MESI_Three_Level. Change-Id: Id68935e2a7d3ccd0e22a59f43a15f167410632a2 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27715 Reviewed-by: Bradford Beckmann Maintainer: Bradford Beckmann Tested-by: kokoro --- M configs/ruby/MESI_Three_Level.py M src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm M src/mem/ruby/protocol/MESI_Three_Level-L1cache.sm M src/mem/ruby/protocol/MESI_Three_Level-msg.sm M src/mem/ruby/protocol/MESI_Two_Level-L2cache.sm M src/mem/ruby/protocol/RubySlicc_Types.sm M src/mem/ruby/structures/CacheMemory.hh M src/mem/ruby/structures/TBETable.hh 8 files changed, 386 insertions(+), 3 deletions(-) Approvals: Bradford Beckmann: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/configs/ruby/MESI_Three_Level.py b/configs/ruby/MESI_Three_Level.py index fdebea4..0e9ef09 100644 --- a/configs/ruby/MESI_Three_Level.py +++ b/configs/ruby/MESI_Three_Level.py @@ -53,6 +53,8 @@ parser.add_option("--l0_transitions_per_cycle", type="int", default=32) parser.add_option("--l1_transitions_per_cycle", type="int", default=32) parser.add_option("--l2_transitions_per_cycle", type="int", default=4) +parser.add_option("--enable-prefetch", action="store_true", default=False,\ +help="Enable Ruby hardware prefetcher") return def create_system(options, full_system, system, dma_ports, bootmem, @@ -118,10 +120,22 @@ else: clk_domain = system.cpu[i].clk_domain +# Ruby prefetcher +prefetcher = RubyPrefetcher.Prefetcher( +num_streams=16, +unit_filter = 256, +nonunit_filter = 256, +train_misses = 5, +num_startup_pfs = 4, +cross_page = False +) + l0_cntrl = L0Cache_Controller( version = i * num_cpus_per_cluster + j, Icache = l0i_cache, Dcache = l0d_cache, transitions_per_cycle = options.l0_transitions_per_cycle, + prefetcher = prefetcher, + enable_prefetch = options.enable_prefetch, send_evictions = send_evicts(options), clk_domain = clk_domain, ruby_system = ruby_system) @@ -159,6 +173,7 @@ l1_cntrl_nodes.append(l1_cntrl) # Connect the L0 and L1 controllers +l0_cntrl.prefetchQueue = MessageBuffer() l0_cntrl.mandatoryQueue = MessageBuffer() l0_cntrl.bufferToL1 = MessageBuffer(ordered = True) l1_cntrl.bufferFromL0 = l0_cntrl.bufferToL1 diff --git a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm index 14fb07a..da89bf5 100644 --- a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm +++ b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm @@ -46,6 +46,9 @@ Cycles response_latency := 2; bool send_evictions; + Prefetcher * prefetcher; + bool enable_prefetch := "False"; + // From this node's L0 cache to the network MessageBuffer * bufferToL1, network="To"; @@ -54,6 +57,9 @@ // Message queue between this controller and the processor MessageBuffer * mandatoryQueue; + + // Request Buffer for prefetches + MessageBuffer * prefetchQueue; { // STATES state_declaration(State, desc="Cache states", default="L0Cache_State_I") { @@ -92,6 +98,11 @@ // processor needs to write to it. So, the controller has requested for // write permission. SM, AccessPermission:Read_Only, desc="Issued GETX, have not seen response yet"; + +// Transient states in which block is being prefetched +PF_Inst_IS, AccessPermission:Busy, desc="Issued GETS, have not seen response yet"; +PF_IS, AccessPermission:Busy, desc="Issued GETS, have not seen response yet"; +PF_IE, AccessPermission:Busy, desc="Issued GETX, have not seen response yet"; } // EVENTS @@ -123,6 +134,12 @@ WB_Ack,desc="Ack for replacement"; Failed_SC,desc="Store conditional request that will fail"; + +// Prefetch events (generated by prefetcher) +PF_L0_Replacement, desc="L0 Replacement caused by pretcher", format="!pr"; +PF_Load, desc="Load request from prefetcher"; +PF_Ifetch, desc="Instruction fetch request from prefetcher"; +PF_Store,desc="Exclusive load request from prefetcher"; } // TYPES @@ -132,6 +149,7 @@ State CacheState,desc="cache state"; DataBlock DataBlk, desc="data for the block";
[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: MESI_Three_Level LL/SC improvements
Pouya Fotouhi has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/28328 ) Change subject: mem-ruby: MESI_Three_Level LL/SC improvements .. mem-ruby: MESI_Three_Level LL/SC improvements This patch fixes the MESI_Three_Level protocols so that it correctly informers the Ruby sequencer when a line eviction occurs. Furthermore, the patch allows the protocol to recognize the 'Store_Conditional' RubyRequestType and shortcuts this operation if the monitored line has been cleared from the address monitor. This prevents certain livelock behaviour in which a line could ping-pong between competing cores. The patch establishes a new C/C++ preprocessor definition which allows the Sequencer to send the 'Store_Conditional' RubyRequestType to MESI_Three_Level instead of 'ST'. This is a temporary measure until the other protocols explicitely recognize 'Store_Conditional'. Change-Id: I27ae041ab0e015a4f54f20df666f9c4873c7583d Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28328 Reviewed-by: Daniel Carvalho Maintainer: Bobby R. Bruce Tested-by: kokoro --- M src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm M src/mem/ruby/system/SConscript M src/mem/ruby/system/Sequencer.cc 3 files changed, 77 insertions(+), 23 deletions(-) Approvals: Daniel Carvalho: Looks good to me, approved Bobby R. Bruce: Looks good to me, approved kokoro: Regressions pass diff --git a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm index b74a727..14fb07a 100644 --- a/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm +++ b/src/mem/ruby/protocol/MESI_Three_Level-L0cache.sm @@ -121,6 +121,8 @@ Ack,desc="Ack for processor"; WB_Ack,desc="Ack for replacement"; + +Failed_SC,desc="Store conditional request that will fail"; } // TYPES @@ -257,7 +259,8 @@ return Event:Load; } else if (type == RubyRequestType:IFETCH) { return Event:Ifetch; -} else if ((type == RubyRequestType:ST) || (type == RubyRequestType:ATOMIC)) { +} else if ((type == RubyRequestType:ST) || (type == RubyRequestType:ATOMIC) + || (type == RubyRequestType:Store_Conditional)) { return Event:Store; } else { error("Invalid RubyRequestType"); @@ -349,36 +352,51 @@ } } } else { - // *** DATA ACCESS *** Entry Dcache_entry := getDCacheEntry(in_msg.LineAddress); + + // early out for failed store conditionals + + if (in_msg.Type == RubyRequestType:Store_Conditional) { + if (!sequencer.llscCheckMonitor(in_msg.LineAddress)) { +trigger(Event:Failed_SC, in_msg.LineAddress, +Dcache_entry, TBEs[in_msg.LineAddress]); +} + } + if (is_valid(Dcache_entry)) { // The tag matches for the L0, so the L0 ask the L1 for it trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress, Dcache_entry, TBEs[in_msg.LineAddress]); } else { - -// Check to see if it is in the OTHER L0 -Entry Icache_entry := getICacheEntry(in_msg.LineAddress); -if (is_valid(Icache_entry)) { - // The block is in the wrong L0, put the request on the queue to the private L1 - trigger(Event:L0_Replacement, in_msg.LineAddress, - Icache_entry, TBEs[in_msg.LineAddress]); -} - -if (Dcache.cacheAvail(in_msg.LineAddress)) { - // L1 does't have the line, but we have space for it - // in the L0 let's see if the L1 has it - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress, - Dcache_entry, TBEs[in_msg.LineAddress]); +// if the request is not valid, the store conditional will fail +if (in_msg.Type == RubyRequestType:Store_Conditional) { +// if the line is not valid, it can't be locked +trigger(Event:Failed_SC, in_msg.LineAddress, +Dcache_entry, TBEs[in_msg.LineAddress]); } else { - // No room in the L1, so we need to make room in the L0 - // Check if the line we want to evict is not locked - Addr addr := Dcache.cacheProbe(in_msg.LineAddress); - check_on_cache_probe(mandatoryQueue_in, addr); - trigger(Event:L0_Replacement, addr, - getDCacheEntry(addr), - TBEs[addr]); + // Check to see if it is in the OTHER L0 + Entry Icache_entry := getICacheEntry(in_msg.LineAddress); + if (is_valid(Icache_entry)) { +// The block is in the wrong L0, put the request on the queue to the private L1 +
[gem5-dev] Change in gem5/gem5[develop]: mem-ruby: LL/SC fixes
Pouya Fotouhi has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/27103 ) Change subject: mem-ruby: LL/SC fixes .. mem-ruby: LL/SC fixes The implementation for load-linked/store-conditional did not work correctly for multi-core simulations. Since load-links were treated as stores, it was not possible for a line to have multiple readers which often resulted in livelock when using these instructions to implemented mutexes. This improved implementation treats load-linked instructions similarly to loads but locks the line after a copy has been fetched locally. Writes to a monitored address ensure the 'linked' property is blown away and any subsequent store-conditional will fail. Change-Id: I19bd74459e26732c92c8b594901936e6439fb073 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27103 Reviewed-by: Daniel Carvalho Maintainer: Bobby R. Bruce Tested-by: kokoro --- M src/mem/ruby/protocol/RubySlicc_Types.sm M src/mem/ruby/system/Sequencer.cc M src/mem/ruby/system/Sequencer.hh 3 files changed, 155 insertions(+), 73 deletions(-) Approvals: Daniel Carvalho: Looks good to me, approved Bobby R. Bruce: Looks good to me, approved kokoro: Regressions pass diff --git a/src/mem/ruby/protocol/RubySlicc_Types.sm b/src/mem/ruby/protocol/RubySlicc_Types.sm index fd76289..f8de9ed 100644 --- a/src/mem/ruby/protocol/RubySlicc_Types.sm +++ b/src/mem/ruby/protocol/RubySlicc_Types.sm @@ -1,4 +1,16 @@ /* + * Copyright (c) 2020 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. @@ -112,6 +124,10 @@ void writeCallback(Addr, DataBlock, bool, MachineType, Cycles, Cycles, Cycles); + // ll/sc support + void writeCallbackScFail(Addr, DataBlock); + bool llscCheckMonitor(Addr); + void checkCoherence(Addr); void evictionCallback(Addr); void recordRequestType(SequencerRequestType); diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 1f538c3..0287e13 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 ARM Limited + * Copyright (c) 2019-2020 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -45,6 +45,7 @@ #include "base/logging.hh" #include "base/str.hh" #include "cpu/testers/rubytest/RubyTester.hh" +#include "debug/LLSC.hh" #include "debug/MemoryAccess.hh" #include "debug/ProtocolTrace.hh" #include "debug/RubySequencer.hh" @@ -90,6 +91,64 @@ } void +Sequencer::llscLoadLinked(const Addr claddr) +{ +AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr); +if (line) { +line->setLocked(m_version); +DPRINTF(LLSC, "LLSC Monitor - inserting load linked - " + "addr=0x%lx - cpu=%u\n", claddr, m_version); +} +} + +void +Sequencer::llscClearMonitor(const Addr claddr) +{ +AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr); +if (line && line->isLocked(m_version)) { +line->clearLocked(); +DPRINTF(LLSC, "LLSC Monitor - clearing due to store - " + "addr=0x%lx - cpu=%u\n", claddr, m_version); +} +} + +bool +Sequencer::llscStoreConditional(const Addr claddr) +{ +AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr); +if (!line) +return false; + +DPRINTF(LLSC, "LLSC Monitor - clearing due to " + "store conditional - " + "addr=0x%lx - cpu=%u\n", + claddr, m_version); + +if (line->isLocked(m_version)) { +line->clearLocked(); +return true; +} else { +line->clearLocked(); +return false; +} +} + +bool +Sequencer::llscCheckMonitor(const Addr address) +{ +const Addr claddr = makeLineAddress(address); +AbstractCacheEntry *line = m_dataCache_ptr->lookup(claddr); +if (!line) +return false; + +if (line->isLocked(m_version)) { +return true; +} else { +return false; +} +} + +void Sequencer::wakeup() { assert(drainState() != DrainState::Draining); @@ -203,62 +262,6 @@ } void -Sequencer::invalidateSC(Addr address) -{ -AbstractCacheEntry *e =
[gem5-dev] Change in gem5/gem5[develop]: util: Add support for multiple call types in the m5 utility.
Gabe Black has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/27242 ) Change subject: util: Add support for multiple call types in the m5 utility. .. util: Add support for multiple call types in the m5 utility. Using mechanisms added in previous CLs, this change modifies the m5 utility so that it can use any of the back ends enabled and implemented by each variant, defaulting to one particular implementation if not is selected explicitly. On x86, the default mechanism is the magic address. All other variants default to the magic instruction since they don't have a well established address to use or even in most cases an implementation to use. The ability to override the particular magic address the utility wants to use (necessary on variants such as aarch64) will be added in a future CL. Change-Id: I5fc414740e30759e7dde719cddcc8d5d41f8cc74 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27242 Reviewed-by: Jason Lowe-Power Reviewed-by: Pouya Fotouhi Maintainer: Gabe Black Tested-by: kokoro --- M util/m5/SConstruct M util/m5/src/SConscript M util/m5/src/aarch64/SConsopts M util/m5/src/aarch64/m5op.S A util/m5/src/aarch64/m5op_addr.S M util/m5/src/addr_call_type.c M util/m5/src/arm/SConsopts M util/m5/src/m5.c M util/m5/src/semi_call_type.c M util/m5/src/sparc/SConsopts M util/m5/src/thumb/SConsopts M util/m5/src/x86/SConsopts M util/m5/src/x86/m5op.S A util/m5/src/x86/m5op_addr.S 14 files changed, 251 insertions(+), 98 deletions(-) Approvals: Jason Lowe-Power: Looks good to me, approved Pouya Fotouhi: Looks good to me, but someone else must approve Gabe Black: Looks good to me, approved kokoro: Regressions pass diff --git a/util/m5/SConstruct b/util/m5/SConstruct index 83d46aa..48073d2 100644 --- a/util/m5/SConstruct +++ b/util/m5/SConstruct @@ -23,6 +23,7 @@ # (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 copy import os main = Environment() @@ -59,11 +60,34 @@ # Use soft links instead of hard links when setting up a build directory. main.SetOption('duplicate', 'soft-copy') +class CallType(object): +def __init__(self, name): +self.name = name +self.impl_file = None +self.enabled = False +self.default = False + +def impl(self, impl, default=False): +self.impl_file = impl +self.enabled = True +self.default = default + +call_types = { +# Magic instruction. +'inst': CallType('inst'), +# Magic address. +'addr': CallType('addr'), +# Semihosting extension. +'semi': CallType('semi'), +} + for root, dirs, files in os.walk(abspath(src_dir)): # Each SConsopts file describes a variant of the m5 utility. if 'SConsopts' in files: env = main.Clone() +env['CALL_TYPE'] = copy.deepcopy(call_types) + # The user may override variant settings by setting environment # variables of the form ${VARIANT}.${OPTION}. For instance, to set the # CROSS_COMPILE prefix for variant foo to bar-, the user would set an diff --git a/util/m5/src/SConscript b/util/m5/src/SConscript index 392ac9e..c2a3ede 100644 --- a/util/m5/src/SConscript +++ b/util/m5/src/SConscript @@ -29,30 +29,47 @@ # Raw source files. m5_mmap = 'm5_mmap.c' -m5op = '${VARIANT}/m5op.S' m5 = 'm5.c' jni = 'jni_gem5Op.c' lua = 'lua_gem5Op.c' +all_call_types = list(env['CALL_TYPE'].values()) +call_types = list([ ct for ct in all_call_types if ct.enabled ]) +m5ops = list([ '${VARIANT}/%s' % ct.impl_file for ct in call_types ]) + +default_call_type = list([ ct for ct in call_types if ct.default ]) +assert len(default_call_type) == 1, \ +'There should be exactly one default call type for %s, found %d' % \ +(env['VARIANT'], len(default_call_type)) +default_call_type = default_call_type[0] + static_env = env.Clone() static_env.Append(LINKFLAGS=[ '-no-pie', '-static' ]) +for ct in all_call_types: +static_env.Append(CFLAGS='-DENABLE_CT_%s=%d' % +(ct.name, 1 if ct.enabled else 0)) +static_env.Append(CFLAGS='-DDEFAULT_CT_%s=%d' % +(ct.name, 1 if ct.default else 0)) +static_env.Append(CFLAGS='-DDEFAULT_CALL_TYPE=%s' % default_call_type.name) + # # The m5 library for use in other C/C++ programs. # -libm5 = static_env.StaticLibrary('out/m5', [ m5op, m5_mmap ]) +libm5 = static_env.StaticLibrary('out/m5', [ m5_mmap ] + m5ops) # # The m5 stand alone command line utility. # -m5_bin = static_env.Program('out/m5', [ m5, m5_mmap, libm5 ]) +ct_support = list([ File('%s_call_type.c' % ct.name) for ct in call_types ]) +m5_bin = static_env.Program('out/m5', ct_support + [ m5, m5_mmap, libm5 ]) # The shared version of the m5 op call sights, used by mutliple targets below. shared_env = env.Clone()