diff options
author | Derek Hower <drh5@cs.wisc.edu> | 2009-07-18 17:40:20 -0500 |
---|---|---|
committer | Derek Hower <drh5@cs.wisc.edu> | 2009-07-18 17:40:20 -0500 |
commit | 926ab6e6dbc2417f6c103512481a60e64be4fea8 (patch) | |
tree | d8598dd4a0841928729ebde1f0b00882e6498604 /src/mem/ruby/system/Sequencer.cc | |
parent | 4b7ea4cb510465bc82c6679407d5a125cfddd18c (diff) | |
parent | d85cd08113e61817fdf1df978f2713ba8b094996 (diff) | |
download | gem5-926ab6e6dbc2417f6c103512481a60e64be4fea8.tar.xz |
merge
Diffstat (limited to 'src/mem/ruby/system/Sequencer.cc')
-rw-r--r-- | src/mem/ruby/system/Sequencer.cc | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 97416d2d3..1587aa5fa 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -43,6 +43,8 @@ //Sequencer::Sequencer(int core_id, MessageBuffer* mandatory_q) +#define LLSC_FAIL -2 + Sequencer::Sequencer(const string & name) :RubyPort(name) { @@ -201,7 +203,10 @@ bool Sequencer::insertRequest(SequencerRequest* request) { Address line_addr(request->ruby_request.paddr); line_addr.makeLineAddress(); if ((request->ruby_request.type == RubyRequestType_ST) || - (request->ruby_request.type == RubyRequestType_RMW)) { + (request->ruby_request.type == RubyRequestType_RMW_Read) || + (request->ruby_request.type == RubyRequestType_RMW_Write) || + (request->ruby_request.type == RubyRequestType_Locked_Read) || + (request->ruby_request.type == RubyRequestType_Locked_Write)) { if (m_writeRequestTable.exist(line_addr)) { m_writeRequestTable.lookup(line_addr) = request; // return true; @@ -237,7 +242,10 @@ void Sequencer::removeRequest(SequencerRequest* srequest) { Address line_addr(ruby_request.paddr); line_addr.makeLineAddress(); if ((ruby_request.type == RubyRequestType_ST) || - (ruby_request.type == RubyRequestType_RMW)) { + (ruby_request.type == RubyRequestType_RMW_Read) || + (ruby_request.type == RubyRequestType_RMW_Write) || + (ruby_request.type == RubyRequestType_Locked_Read) || + (ruby_request.type == RubyRequestType_Locked_Write)) { m_writeRequestTable.deallocate(line_addr); } else { m_readRequestTable.deallocate(line_addr); @@ -256,7 +264,14 @@ void Sequencer::writeCallback(const Address& address, DataBlock& data) { removeRequest(request); assert((request->ruby_request.type == RubyRequestType_ST) || - (request->ruby_request.type == RubyRequestType_RMW)); + (request->ruby_request.type == RubyRequestType_RMW_Read) || + (request->ruby_request.type == RubyRequestType_RMW_Write) || + (request->ruby_request.type == RubyRequestType_Locked_Read) || + (request->ruby_request.type == RubyRequestType_Locked_Write)); + // POLINA: the assumption is that atomics are only on data cache and not instruction cache + if (request->ruby_request.type == RubyRequestType_Locked_Read) { + m_dataCache_ptr->setLocked(address, m_version); + } hitCallback(request, data); } @@ -347,6 +362,7 @@ bool Sequencer::empty() const { return (m_writeRequestTable.size() == 0) && (m_readRequestTable.size() == 0); } + int64_t Sequencer::makeRequest(const RubyRequest & request) { assert(Address(request.paddr).getOffset() + request.len <= RubySystem::getBlockSizeBytes()); @@ -355,6 +371,16 @@ int64_t Sequencer::makeRequest(const RubyRequest & request) SequencerRequest *srequest = new SequencerRequest(request, id, g_eventQueue_ptr->getTime()); bool found = insertRequest(srequest); if (!found) + if (request.type == RubyRequestType_Locked_Write) { + // NOTE: it is OK to check the locked flag here as the mandatory queue will be checked first + // ensuring that nothing comes between checking the flag and servicing the store + if (!m_dataCache_ptr->isLocked(line_address(Address(request.paddr)), m_version)) { + return LLSC_FAIL; + } + else { + m_dataCache_ptr->clearLocked(line_address(Address(request.paddr))); + } + } issueRequest(request); // TODO: issue hardware prefetches here @@ -379,7 +405,16 @@ void Sequencer::issueRequest(const RubyRequest& request) { case RubyRequestType_ST: ctype = CacheRequestType_ST; break; - case RubyRequestType_RMW: + case RubyRequestType_Locked_Read: + ctype = CacheRequestType_ST; + break; + case RubyRequestType_Locked_Write: + ctype = CacheRequestType_ST; + break; + case RubyRequestType_RMW_Read: + ctype = CacheRequestType_ATOMIC; + break; + case RubyRequestType_RMW_Write: ctype = CacheRequestType_ATOMIC; break; default: |