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 ---