locked_mem.hh (10030:b531e328342d) | locked_mem.hh (10037:5cac77888310) |
---|---|
1/* 2 * Copyright (c) 2012-2013 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 39 unchanged lines hidden (view full) --- 48 49/** 50 * @file 51 * 52 * ISA-specific helper functions for locked memory accesses. 53 */ 54 55#include "arch/arm/miscregs.hh" | 1/* 2 * Copyright (c) 2012-2013 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 39 unchanged lines hidden (view full) --- 48 49/** 50 * @file 51 * 52 * ISA-specific helper functions for locked memory accesses. 53 */ 54 55#include "arch/arm/miscregs.hh" |
56#include "arch/arm/isa_traits.hh" 57#include "debug/LLSC.hh" |
|
56#include "mem/packet.hh" 57#include "mem/request.hh" 58 59namespace ArmISA 60{ 61template <class XC> 62inline void 63handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask) 64{ | 58#include "mem/packet.hh" 59#include "mem/request.hh" 60 61namespace ArmISA 62{ 63template <class XC> 64inline void 65handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask) 66{ |
67 DPRINTF(LLSC,"%s: handleing snoop for address: %#x locked: %d\n", 68 xc->getCpuPtr()->name(),pkt->getAddr(), 69 xc->readMiscReg(MISCREG_LOCKFLAG)); |
|
65 if (!xc->readMiscReg(MISCREG_LOCKFLAG)) 66 return; 67 68 Addr locked_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask; | 70 if (!xc->readMiscReg(MISCREG_LOCKFLAG)) 71 return; 72 73 Addr locked_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask; |
74 // If no caches are attached, the snoop address always needs to be masked |
|
69 Addr snoop_addr = pkt->getAddr() & cacheBlockMask; 70 | 75 Addr snoop_addr = pkt->getAddr() & cacheBlockMask; 76 |
71 if (locked_addr == snoop_addr) | 77 DPRINTF(LLSC,"%s: handleing snoop for address: %#x locked addr: %#x\n", 78 xc->getCpuPtr()->name(),snoop_addr, locked_addr); 79 if (locked_addr == snoop_addr) { 80 DPRINTF(LLSC,"%s: address match, clearing lock and signaling sev\n", 81 xc->getCpuPtr()->name()); |
72 xc->setMiscReg(MISCREG_LOCKFLAG, false); | 82 xc->setMiscReg(MISCREG_LOCKFLAG, false); |
83 // Implement ARMv8 WFE/SEV semantics 84 xc->setMiscReg(MISCREG_SEV_MAILBOX, true); 85 xc->getCpuPtr()->wakeup(); 86 } |
|
73} 74 75template <class XC> 76inline void | 87} 88 89template <class XC> 90inline void |
77handleLockedSnoopHit(XC *xc) | 91handleLockedRead(XC *xc, Request *req) |
78{ | 92{ |
93 xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr()); 94 xc->setMiscReg(MISCREG_LOCKFLAG, true); 95 DPRINTF(LLSC,"%s: Placing address %#x in monitor\n", xc->getCpuPtr()->name(), 96 req->getPaddr()); |
|
79} 80 81template <class XC> 82inline void | 97} 98 99template <class XC> 100inline void |
83handleLockedRead(XC *xc, Request *req) | 101handleLockedSnoopHit(XC *xc) |
84{ | 102{ |
85 xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr()); 86 xc->setMiscReg(MISCREG_LOCKFLAG, true); | 103 DPRINTF(LLSC,"%s: handling snoop lock hit address: %#x\n", 104 xc->getCpuPtr()->name(), xc->readMiscReg(MISCREG_LOCKADDR)); 105 xc->setMiscReg(MISCREG_LOCKFLAG, false); 106 xc->setMiscReg(MISCREG_SEV_MAILBOX, true); |
87} 88 | 107} 108 |
89 | |
90template <class XC> 91inline bool 92handleLockedWrite(XC *xc, Request *req, Addr cacheBlockMask) 93{ 94 if (req->isSwap()) 95 return true; 96 | 109template <class XC> 110inline bool 111handleLockedWrite(XC *xc, Request *req, Addr cacheBlockMask) 112{ 113 if (req->isSwap()) 114 return true; 115 |
116 DPRINTF(LLSC,"%s: handling locked write for address %#x in monitor\n", 117 xc->getCpuPtr()->name(), req->getPaddr()); |
|
97 // Verify that the lock flag is still set and the address 98 // is correct 99 bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG); 100 Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask; 101 if (!lock_flag || (req->getPaddr() & cacheBlockMask) != lock_addr) { 102 // Lock flag not set or addr mismatch in CPU; 103 // don't even bother sending to memory system 104 req->setExtraData(0); 105 xc->setMiscReg(MISCREG_LOCKFLAG, false); | 118 // Verify that the lock flag is still set and the address 119 // is correct 120 bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG); 121 Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask; 122 if (!lock_flag || (req->getPaddr() & cacheBlockMask) != lock_addr) { 123 // Lock flag not set or addr mismatch in CPU; 124 // don't even bother sending to memory system 125 req->setExtraData(0); 126 xc->setMiscReg(MISCREG_LOCKFLAG, false); |
127 DPRINTF(LLSC,"%s: clearing lock flag in handle locked write\n", 128 xc->getCpuPtr()->name()); |
|
106 // the rest of this code is not architectural; 107 // it's just a debugging aid to help detect 108 // livelock by warning on long sequences of failed 109 // store conditionals 110 int stCondFailures = xc->readStCondFailures(); 111 stCondFailures++; 112 xc->setStCondFailures(stCondFailures); 113 if (stCondFailures % 100000 == 0) { --- 15 unchanged lines hidden --- | 129 // the rest of this code is not architectural; 130 // it's just a debugging aid to help detect 131 // livelock by warning on long sequences of failed 132 // store conditionals 133 int stCondFailures = xc->readStCondFailures(); 134 stCondFailures++; 135 xc->setStCondFailures(stCondFailures); 136 if (stCondFailures % 100000 == 0) { --- 15 unchanged lines hidden --- |