diff -r 18d8d30c1c45 -r 5f608237e7d7 configs/example/se.py --- a/configs/example/se.py Mon Nov 14 17:46:31 2011 -0600 +++ b/configs/example/se.py Mon Nov 14 17:48:36 2011 -0600 @@ -155,12 +155,12 @@ if options.ruby: if options.detailed: - print >> sys.stderr, "Ruby only works with TimingSimpleCPU!!" - sys.exit(1) - elif not options.timing: - print >> sys.stderr, "****WARN: using Timing CPU since it's needed by Ruby" + class CPUClass(DerivO3CPU): pass + else: + if not options.timing: + print >> sys.stderr, "****WARN: using Timing CPU since it's needed by Ruby" + class CPUClass(TimingSimpleCPU): pass - class CPUClass(TimingSimpleCPU): pass test_mem_mode = 'timing' FutureClass = None else: @@ -184,7 +184,7 @@ CacheConfig.config_cache(options, system) for i in xrange(np): - system.cpu[i].workload = multiprocesses[i] + system.cpu[i].workload = multiprocesses[0] if options.ruby: system.cpu[i].icache_port = system.ruby._cpu_ruby_ports[i].port diff -r 18d8d30c1c45 -r 5f608237e7d7 configs/ruby/MESI_CMP_directory.py --- a/configs/ruby/MESI_CMP_directory.py Mon Nov 14 17:46:31 2011 -0600 +++ b/configs/ruby/MESI_CMP_directory.py Mon Nov 14 17:48:36 2011 -0600 @@ -72,6 +72,7 @@ block_size_bits = int(math.log(options.cacheline_size, 2)) cntrl_count = 0 + send_invalidations = options.detailed for i in xrange(options.num_cpus): # @@ -89,6 +90,7 @@ L1IcacheMemory = l1i_cache, L1DcacheMemory = l1d_cache, l2_select_num_bits = l2_bits, + send_invalidations = send_invalidations, ruby_system = ruby_system) cpu_seq = RubySequencer(version = i, diff -r 18d8d30c1c45 -r 5f608237e7d7 src/mem/protocol/MESI_CMP_directory-L1cache.sm --- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm Mon Nov 14 17:46:31 2011 -0600 +++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm Mon Nov 14 17:48:36 2011 -0600 @@ -34,7 +34,8 @@ int l2_select_num_bits, int l1_request_latency = 2, int l1_response_latency = 2, - int to_l2_latency = 1 + int to_l2_latency = 1, + bool send_invalidations { // NODE L1 CACHE // From this node's L1 cache TO the network @@ -544,6 +545,13 @@ } } + action(cc_squash_speculation, "\cc", desc="squash speculative instructions") { + if (send_invalidations) { + DPRINTF(RubySlicc, "Sending invalidation for %s to the CPU\n", address); + sequencer.invalidateCallback(address); + } + } + action(g_issuePUTX, "g", desc="send data to the L2 cache") { enqueue(requestIntraChipL1Network_out, RequestMsg, latency=l1_response_latency) { @@ -748,10 +756,12 @@ } transition(S, L1_Replacement, I) { + cc_squash_speculation; ff_deallocateL1CacheBlock; } transition(S, Inv, I) { + cc_squash_speculation; fi_sendInvAck; l_popRequestQueue; } @@ -770,6 +780,7 @@ transition(E, L1_Replacement, M_I) { // silent E replacement?? + cc_squash_speculation; i_allocateTBE; g_issuePUTX; // send data, but hold in case forwarded request ff_deallocateL1CacheBlock; @@ -777,11 +788,13 @@ transition(E, Inv, I) { // don't send data + cc_squash_speculation; fi_sendInvAck; l_popRequestQueue; } transition(E, Fwd_GETX, I) { + cc_squash_speculation; d_sendDataToRequestor; l_popRequestQueue; } @@ -804,6 +817,7 @@ } transition(M, L1_Replacement, M_I) { + cc_squash_speculation; i_allocateTBE; g_issuePUTX; // send data, but hold in case forwarded request ff_deallocateL1CacheBlock; @@ -815,6 +829,7 @@ } transition(M, Inv, I) { + cc_squash_speculation; f_sendDataToL2; l_popRequestQueue; } @@ -825,6 +840,7 @@ } transition(M, Fwd_GETX, I) { + cc_squash_speculation; d_sendDataToRequestor; l_popRequestQueue; } @@ -948,6 +964,3 @@ o_popIncomingResponseQueue; } } - - - diff -r 18d8d30c1c45 -r 5f608237e7d7 src/mem/protocol/RubySlicc_Types.sm --- a/src/mem/protocol/RubySlicc_Types.sm Mon Nov 14 17:46:31 2011 -0600 +++ b/src/mem/protocol/RubySlicc_Types.sm Mon Nov 14 17:48:36 2011 -0600 @@ -107,6 +107,7 @@ void writeCallback(Address, GenericMachineType, DataBlock, Time, Time, Time); void checkCoherence(Address); void profileNack(Address, int, int, uint64); + void invalidateCallback(Address); } structure(RubyRequest, desc="...", interface="Message", external="yes") { diff -r 18d8d30c1c45 -r 5f608237e7d7 src/mem/ruby/system/RubyPort.hh --- a/src/mem/ruby/system/RubyPort.hh Mon Nov 14 17:46:31 2011 -0600 +++ b/src/mem/ruby/system/RubyPort.hh Mon Nov 14 17:48:36 2011 -0600 @@ -1,5 +1,6 @@ /* * Copyright (c) 2009 Advanced Micro Devices, Inc. + * Copyright (c) 2011 Mark D. Hill and David A. Wood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -59,6 +60,7 @@ RubySystem*_system, bool _access_phys_mem); bool sendTiming(PacketPtr pkt); void hitCallback(PacketPtr pkt); + void invalidateCallback(const Address& address); unsigned deviceBlockSize() const; bool onRetryList() @@ -125,7 +127,7 @@ protected: const std::string m_name; void ruby_hit_callback(PacketPtr pkt); - void hit(PacketPtr pkt); + void ruby_invalidate_callback(const Address& address); int m_version; AbstractController* m_controller; @@ -156,6 +158,7 @@ // that should be called when the Sequencer becomes available after a stall. // std::list retryList; + std::list portList; bool waitingOnSequencer; bool access_phys_mem; diff -r 18d8d30c1c45 -r 5f608237e7d7 src/mem/ruby/system/RubyPort.cc --- a/src/mem/ruby/system/RubyPort.cc Mon Nov 14 17:46:31 2011 -0600 +++ b/src/mem/ruby/system/RubyPort.cc Mon Nov 14 17:48:36 2011 -0600 @@ -1,5 +1,6 @@ /* * Copyright (c) 2009 Advanced Micro Devices, Inc. + * Copyright (c) 2011 Mark D. Hill and David A. Wood * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,8 +67,10 @@ RubyPort::getPort(const std::string &if_name, int idx) { if (if_name == "port") { - return new M5Port(csprintf("%s-port%d", name(), idx), this, - ruby_system, access_phys_mem); + M5Port* m5Port = new M5Port(csprintf("%s-port%d", name(), idx), this, + ruby_system, access_phys_mem); + portList.push_back(m5Port); + return m5Port; } if (if_name == "pio_port") { @@ -608,3 +611,16 @@ { return (unsigned) RubySystem::getBlockSizeBytes(); } + +void +RubyPort::ruby_invalidate_callback(const Address& address) +{ + DPRINTF(RubyPort, "Sending invalidations.\n"); + Request req(address.getAddress(), 0, 0); + for (std::list::iterator it = portList.begin(); + it != portList.end(); + it++) { + Packet *pkt = new Packet(&req, MemCmd::ReadExReq, -1); + (*it)->sendTiming(pkt); + } +} diff -r 18d8d30c1c45 -r 5f608237e7d7 src/mem/ruby/system/Sequencer.hh --- a/src/mem/ruby/system/Sequencer.hh Mon Nov 14 17:46:31 2011 -0600 +++ b/src/mem/ruby/system/Sequencer.hh Mon Nov 14 17:48:36 2011 -0600 @@ -119,6 +119,8 @@ Time forwardRequestTime, Time firstResponseTime); + void invalidateCallback(const Address& address); + RequestStatus insertRequest(PacketPtr pkt, RubyRequestType request_type); bool handleLlsc(const Address& address, SequencerRequest* request); @@ -171,4 +173,3 @@ } #endif // __MEM_RUBY_SYSTEM_SEQUENCER_HH__ - diff -r 18d8d30c1c45 -r 5f608237e7d7 src/mem/ruby/system/Sequencer.cc --- a/src/mem/ruby/system/Sequencer.cc Mon Nov 14 17:46:31 2011 -0600 +++ b/src/mem/ruby/system/Sequencer.cc Mon Nov 14 17:48:36 2011 -0600 @@ -724,3 +724,9 @@ g_system_ptr->checkGlobalCoherenceInvariant(addr); #endif } + +void +Sequencer::invalidateCallback(const Address& address) +{ + ruby_invalidate_callback(address); +}