26a6c4a09edf8e459e3a1a27c4b4d4f3755ff75a
1 // Copyright (c) 2015 ARM Limited
2 // All rights reserved.
4 // The license below extends only to copyright in the software and shall
5 // not be construed as granting a license to any other intellectual
6 // property including but not limited to intellectual property relating
7 // to a hardware implementation of the functionality of the software
8 // licensed hereunder. You may use the software subject to the license
9 // terms below provided that you ensure that this notice is replicated
10 // unmodified and in its entirety in all distributions of the software,
11 // modified or unmodified, in source code or in binary form.
13 // Redistribution and use in source and binary forms, with or without
14 // modification, are permitted provided that the following conditions are
15 // met: redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer;
17 // redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution;
20 // neither the name of the copyright holders nor the names of its
21 // contributors may be used to endorse or promote products derived from
22 // this software without specific prior written permission.
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // Copyright 2009-2014 Sandia Coporation. Under the terms
37 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
38 // Government retains certain rights in this software.
40 // Copyright (c) 2009-2014, Sandia Corporation
41 // All rights reserved.
43 // For license information, see the LICENSE file in the current directory.
47 #ifdef fatal // gem5 sets this
51 #include <sst_config.h>
53 #include <mem/packet.hh>
55 #include <sst/core/component.h>
56 #include <sst/core/params.h>
57 #include <sst/core/link.h>
58 #include <sst/elements/memHierarchy/memNIC.h>
61 using namespace SST::gem5
;
62 using namespace SST::MemHierarchy
;
64 ExtMaster::ExtMaster(gem5Component
*g
, Output
&o
, ::ExternalMaster
& p
,
66 Port(n
, p
), out(o
), port(p
), simPhase(CONSTRUCTION
),
69 Params _p
; // will be ignored
70 nic
= dynamic_cast<MemNIC
*>(gem5
->loadModuleWithComponent("memHierarchy.memNIC", g
, _p
));
72 MemNIC::ComponentInfo ci
;
74 ci
.link_port
= "network";
75 ci
.link_bandwidth
= "16GB/s";
76 ci
.link_inbuf_size
= "1KB";
77 ci
.link_outbuf_size
= "1KB";
78 ci
.network_addr
= 0; // hard coded at the moment
79 ci
.type
= MemNIC::TypeDirectoryCtrl
;
80 nic
->moduleInit(ci
, new Event::Handler
<ExtMaster
>
81 (this, &ExtMaster::handleEvent
));
85 ExtMaster::init(unsigned phase
)
91 for (auto range
: getAddrRanges()) {
92 MemNIC::ComponentTypeInfo ti
;
93 ti
.rangeStart
= range
.start();
94 ti
.rangeEnd
= range
.end();
95 ti
.interleaveSize
= 0;
96 ti
.interleaveStep
= 0;
106 ExtMaster::setup(void)
114 ExtMaster::finish(void)
120 ExtMaster::clock(void)
126 ExtMaster::handleEvent(SST::Event
* event
)
128 if (simPhase
== CONSTRUCTION
) {
129 out
.fatal(CALL_INFO
, 1, "received Event during Construction phase\n");
132 MemEvent
*ev
= dynamic_cast<MemEvent
*>(event
);
134 out
.fatal(CALL_INFO
, 1, "Can't handle non-MemEvent Event's\n");
137 Command cmdI
= ev
->getCmd(); // command in - SST
138 MemCmd::Command cmdO
; // command out - gem5
142 case GetS
: cmdO
= MemCmd::ReadReq
; break;
143 case GetX
: cmdO
= MemCmd::WriteReq
; data
= true; break;
161 out
.fatal(CALL_INFO
, 1, "Don't know how to convert "
162 "SST command %s to gem5\n",
163 CommandString
[cmdI
]);
166 Request::FlagsType flags
= 0;
167 if (ev
->queryFlag(MemEvent::F_LOCKED
))
168 flags
|= Request::LOCKED_RMW
;
169 if (ev
->queryFlag(MemEvent::F_NONCACHEABLE
))
170 flags
|= Request::UNCACHEABLE
;
171 if (ev
->isLoadLink()) {
172 assert(cmdI
== GetS
);
173 cmdO
= MemCmd::LoadLockedReq
;
174 } else if (ev
->isStoreConditional()) {
175 assert(cmdI
== GetX
);
176 cmdO
= MemCmd::StoreCondReq
;
179 auto req
= new Request(ev
->getAddr(), ev
->getSize(), flags
, 0);
180 req
->setThreadContext(ev
->getGroupId(), 0);
182 auto pkt
= new Packet(req
, cmdO
);
185 pkt
->setData(ev
->getPayload().data());
187 pkt
->pushSenderState(new SenderState(ev
));
189 if (blocked() || !sendTimingReq(pkt
))
190 sendQ
.push_back(pkt
);
194 ExtMaster::recvTimingResp(PacketPtr pkt
) {
195 if (simPhase
== INIT
) {
196 out
.fatal(CALL_INFO
, 1, "not prepared to handle INIT-phase traffic\n");
199 // get original SST packet from gem5 SenderState
200 auto senderState
= dynamic_cast<SenderState
*>(pkt
->popSenderState());
202 out
.fatal(CALL_INFO
, 1, "gem5 senderState corrupt\n");
204 // make (new) response packet, discard (old) original request
205 MemEvent
* ev
= senderState
->event
;
208 MemEvent
* resp
= ev
->makeResponse();
211 // copy the payload and then destroy gem5 packet
212 resp
->setPayload(pkt
->getSize(), pkt
->getPtr
<uint8_t>());
221 ExtMaster::recvReqRetry() {
222 while (blocked() && sendTimingReq(sendQ
.front())) {
228 ExtMaster::recvRangeChange() {
229 for (auto range
: getAddrRanges()) {
230 if (ranges
.find(range
) == ranges
.end()) { // i.e. if not found,
231 MemNIC::ComponentTypeInfo ti
; // indicating a new range.
232 ti
.rangeStart
= range
.start();
233 ti
.rangeEnd
= range
.end();
234 ti
.interleaveSize
= 0;
235 ti
.interleaveStep
= 0;
236 nic
->addTypeInfo(ti
);
237 ranges
.insert(range
);