1/* 2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 303 unchanged lines hidden (view full) --- 312 } 313 314 markRemoved(); 315} 316 317void 318Sequencer::invalidateSC(Addr address) 319{ |
320 RequestTable::iterator i = m_writeRequestTable.find(address); 321 if (i != m_writeRequestTable.end()) { 322 SequencerRequest* request = i->second; 323 // The controller has lost the coherence permissions, hence the lock 324 // on the cache line maintained by the cache should be cleared. 325 if (request->m_type == RubyRequestType_Store_Conditional) { 326 m_dataCache_ptr->clearLocked(address); 327 } |
328 } 329} 330 331bool 332Sequencer::handleLlsc(Addr address, SequencerRequest* request) 333{ |
334 // |
335 // The success flag indicates whether the LLSC operation was successful. 336 // LL ops will always succeed, but SC may fail if the cache line is no 337 // longer locked. |
338 // |
339 bool success = true; 340 if (request->m_type == RubyRequestType_Store_Conditional) { |
341 if (!m_dataCache_ptr->isLocked(address, m_version)) { |
342 // 343 // For failed SC requests, indicate the failure to the cpu by 344 // setting the extra data to zero. 345 // 346 request->pkt->req->setExtraData(0); 347 success = false; 348 } else { 349 // 350 // For successful SC requests, indicate the success to the cpu by 351 // setting the extra data to one. 352 // 353 request->pkt->req->setExtraData(1); 354 } 355 // 356 // Independent of success, all SC operations must clear the lock 357 // |
358 m_dataCache_ptr->clearLocked(address); |
359 } else if (request->m_type == RubyRequestType_Load_Linked) { 360 // 361 // Note: To fully follow Alpha LLSC semantics, should the LL clear any 362 // previously locked cache lines? 363 // |
364 m_dataCache_ptr->setLocked(address, m_version); 365 } else if ((m_dataCache_ptr->isTagPresent(address)) && 366 (m_dataCache_ptr->isLocked(address, m_version))) { |
367 // 368 // Normal writes should clear the locked address 369 // |
370 m_dataCache_ptr->clearLocked(address); |
371 } 372 return success; 373} 374 375void 376Sequencer::recordMissLatency(const Cycles cycles, const RubyRequestType type, 377 const MachineType respondingMach, 378 bool isExternalHit, Cycles issuedTime, --- 114 unchanged lines hidden (view full) --- 493void 494Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data, 495 bool llscSuccess, 496 const MachineType mach, const bool externalHit, 497 const Cycles initialRequestTime, 498 const Cycles forwardRequestTime, 499 const Cycles firstResponseTime) 500{ |
501 PacketPtr pkt = srequest->pkt; 502 Addr request_address(pkt->getAddr()); |
503 Addr request_line_address = makeLineAddress(pkt->getAddr()); |
504 RubyRequestType type = srequest->m_type; 505 Cycles issued_time = srequest->issue_time; 506 |
507 // Set this cache entry to the most recently used 508 if (type == RubyRequestType_IFETCH) { 509 m_instCache_ptr->setMRU(request_line_address); 510 } else { 511 m_dataCache_ptr->setMRU(request_line_address); 512 } 513 |
514 assert(curCycle() >= issued_time); 515 Cycles total_latency = curCycle() - issued_time; 516 517 // Profile the latency for all demand accesses. 518 recordMissLatency(total_latency, type, mach, externalHit, issued_time, 519 initialRequestTime, forwardRequestTime, 520 firstResponseTime, curCycle()); 521 --- 313 unchanged lines hidden --- |