diff -r 5fbc6bd9de63 -r ed4ab740741c configs/example/se.py --- a/configs/example/se.py Sun Oct 30 18:29:48 2011 -0500 +++ b/configs/example/se.py Sun Oct 30 20:14:48 2011 -0500 @@ -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 5fbc6bd9de63 -r ed4ab740741c configs/ruby/MESI_CMP_directory.py --- a/configs/ruby/MESI_CMP_directory.py Sun Oct 30 18:29:48 2011 -0500 +++ b/configs/ruby/MESI_CMP_directory.py Sun Oct 30 20:14:48 2011 -0500 @@ -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 5fbc6bd9de63 -r ed4ab740741c src/mem/protocol/MESI_CMP_directory-L1cache.sm --- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm Sun Oct 30 18:29:48 2011 -0500 +++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm Sun Oct 30 20:14:48 2011 -0500 @@ -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 @@ -679,6 +680,13 @@ mandatoryQueue_in.recycle(); } + 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); + } + } + //***************************************************** // TRANSITIONS @@ -733,10 +741,12 @@ } transition(S, L1_Replacement, I) { + cc_squash_speculation; ff_deallocateL1CacheBlock; } transition(S, Inv, I) { + cc_squash_speculation; fi_sendInvAck; l_popRequestQueue; } @@ -755,6 +765,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; @@ -762,11 +773,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; } @@ -789,6 +802,7 @@ } transition(M, L1_Replacement, M_I) { + cc_squash_speculation; i_allocateTBE; g_issuePUTX; // send data, but hold in case forwarded request ff_deallocateL1CacheBlock; @@ -800,6 +814,7 @@ } transition(M, Inv, I) { + cc_squash_speculation; f_sendDataToL2; l_popRequestQueue; } @@ -810,6 +825,7 @@ } transition(M, Fwd_GETX, I) { + cc_squash_speculation; d_sendDataToRequestor; l_popRequestQueue; } @@ -933,6 +949,3 @@ o_popIncomingResponseQueue; } } - - - diff -r 5fbc6bd9de63 -r ed4ab740741c src/mem/protocol/RubySlicc_Types.sm --- a/src/mem/protocol/RubySlicc_Types.sm Sun Oct 30 18:29:48 2011 -0500 +++ b/src/mem/protocol/RubySlicc_Types.sm Sun Oct 30 20:14:48 2011 -0500 @@ -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 5fbc6bd9de63 -r ed4ab740741c src/mem/ruby/system/RubyPort.hh --- a/src/mem/ruby/system/RubyPort.hh Sun Oct 30 18:29:48 2011 -0500 +++ b/src/mem/ruby/system/RubyPort.hh Sun Oct 30 20:14:48 2011 -0500 @@ -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 5fbc6bd9de63 -r ed4ab740741c src/mem/ruby/system/RubyPort.cc --- a/src/mem/ruby/system/RubyPort.cc Sun Oct 30 18:29:48 2011 -0500 +++ b/src/mem/ruby/system/RubyPort.cc Sun Oct 30 20:14:48 2011 -0500 @@ -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 @@ -70,8 +71,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") { @@ -674,3 +677,19 @@ { return (unsigned) RubySystem::getBlockSizeBytes(); } + +void +RubyPort::ruby_invalidate_callback(const Address& address) +{ + DPRINTF(RubyPort, "Sending invalidations.\n"); + for (std::list::iterator it = portList.begin(); + it != portList.end(); + it++) { + + RequestPtr req = new Request(address.getAddress(), 0, 0); + Packet *pkt = new Packet(req, MemCmd::InvalidCmd, -1); + pkt->setExpressSnoop(); + pkt->assertMemInhibit(); + (*it)->sendTiming(pkt); + } +} diff -r 5fbc6bd9de63 -r ed4ab740741c src/mem/ruby/system/Sequencer.hh --- a/src/mem/ruby/system/Sequencer.hh Sun Oct 30 18:29:48 2011 -0500 +++ b/src/mem/ruby/system/Sequencer.hh Sun Oct 30 20:14:48 2011 -0500 @@ -100,6 +100,8 @@ Time forwardRequestTime, Time firstResponseTime); + void invalidateCallback(const Address& address); + RequestStatus makeRequest(const RubyRequest & request); RequestStatus getRequestStatus(const RubyRequest& request); bool empty() const; diff -r 5fbc6bd9de63 -r ed4ab740741c src/mem/ruby/system/Sequencer.cc --- a/src/mem/ruby/system/Sequencer.cc Sun Oct 30 18:29:48 2011 -0500 +++ b/src/mem/ruby/system/Sequencer.cc Sun Oct 30 20:14:48 2011 -0500 @@ -732,3 +732,9 @@ g_system_ptr->checkGlobalCoherenceInvariant(addr); #endif } + +void +Sequencer::invalidateCallback(const Address& address) +{ + ruby_invalidate_callback(address); +}